lit-element: 2 way data binding not working

I’m expecting 2 way data binding to work similar to polymer templates but I can’t get it to work. For example using a <paper-toggle-button checked="${toggled}"> only works in one direction (reading, but not writing).

I have also tried <paper-toggle-button checked="[[${toggled}]]"> and <paper-toggle-button checked="[[toggled]]">

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 2
  • Comments: 16 (11 by maintainers)

Most upvoted comments

Welcome to 2018, everyone is writing his own lit-element implementation 😀

@web-padawan Could you please explain what’s wrong with two-way data binding (upward data flow)? Two-way data binding was (is) my favorite feature of Polymer. What are the advantages of unidirectional data flow?

This is the expected behaviour since you aren’t using Polymer’s templating system with lit-element, you are using lit-html’s, which doesn’t support 2-way binding for performance reasons. [[ ]] and {{ }} also don’t mean anything to lit-html. The correct way to pass data upwards in lit (and in other one way systems like React), is to use events. In your case, you should listen for on-checked-changed on the paper toggle, and then create a handler that sets the toggled property to the value you get from the event.

For completion. Here is the working element

import { LitElement, html } from '../node_modules/@polymer/lit-element/lit-element.js'
import "../node_modules/@polymer/paper-toggle-button/paper-toggle-button.js";

export class TestPageTwo extends LitElement {

  constructor() {
    super();
    this.toggled = false;
  }

  // properties, observers, etc. are identical to 2.x
  static get properties() {
    return {
      toggled: Boolean
    }
  }

  onCheckedChanged(e) {
    this.toggled = e.detail.value;
  }

  render({toggled}) {
    return html`
    ${toggled}
    <paper-toggle-button checked="${toggled}" on-checked-changed="${this.onCheckedChanged.bind(this)}"></paper-toggle-button>
     `;
  }
}

customElements.define('test-page-two', TestPageTwo);

@BrandiATMuhkuh I believe _render should be used instead of render in your last code. 😉