Search code examples
polymer-2.xvaadin-elements

element not updated when data changes


I have a vaadin-checkbox:

<vaadin-checkbox id=[[item.id]] disabled="true" checked="[[item.checked]]">[[item.description]]</vaadin-checkbox>

I defined my properties:

static get properties() {
    return {
        items: {
            type: Array,
            notify: true,
            value: function() {
                return [];
            }
        }
    };
}

When I now change the data by pressing some button:

_selectItem(event) {
    const item = event.model.item;

    if (item.checked === true) {
        this.$.grid.deselectItem(item);
    } else {
        this.$.grid.selectItem(item);
    }

    item.checked = !item.checked;
}

The state of the checkbox is still checked="true". Why isnt the checkbox getting updated? The same thing when I change the description of the item:

_selectItem(event) {
    event.model.item.description = 'test';
}

The test description is never appearing. The checkbox is never getting updated.


Solution

  • The reason why the checkbox does not get updated by the button click handler is in the Polymer 2 data system. Polymer does not detect the change and does not update the template accordingly.

    In order to make the change in a way that Polymer would detect it you have two options:

    • Use this.set(`items.${event.model.index}.checked`, !item.checked) if you can reliably assume that the index used by dom-repeat always matches that elements's index in the items array (it is not the case if you use sorting or filtering features of dom-repeat). See an example here https://jsfiddle.net/vlukashov/epd0dn2j/
    • If you do not know the index of the updated item in the items array, you can also use the Polymer.MutableData mixin and notify Polymer that something has changed inside the items array without specifying the index of the changed item. This is done by calling this.notifyPath('items') after making a change. However, this requires that your element extends the Polymer.MutableData mixin, and that dom-repeat has the mutable-data attribute set. See an example here: https://jsfiddle.net/vlukashov/epd0dn2j/24/

    More information on this in the Polymer 2 docs.