简体   繁体   中英

Polymer 1.0 Dom-repeat with paper-checkbox: uncheck on data changing

I'm dynamically generating paper-checkbox elements by using dom-repeat with items from a data array. Updating the array the checkboxes correcly update, but Polymer does not reset the checked attribute to false. So, if the data changes, the checkboxes correctly update, but they remain checked.

It seems to me that dom-repeat reuses previous created checkboxes by simply changing their attributes. So, when the user clicks on the first checkbox, it remains checked also when dom-repeat regenerate the list of paper-checkbox.

Below there is the code which generates the issue (I tested it only with Chrome). If you click on the first checkbox, and then click on the "Random Items" button, the first checkbox remains checked.

How do I can avoid it? I tried to place the checked attribute to false (checked=false) but it does not work. Of course it can be done via javascript, but I desire to avoid it.

Thanks

 Polymer({ is: "wc-rnd-checkboxes", properties: { data: { type: Array, value: [1, 2, 3, 4, 5] } }, handleRndGenerator: function() { this.data = []; //It simply generates an array of random length between 1 and 5. var length = Math.floor((Math.random() * 5) + 1) for (i=0; i < length; i++) { var irnd = Math.floor((Math.random() * 10) + 1); this.data.push(irnd); } } }); 
 <script src="https://cdn.rawgit.com/download/polymer-cdn/1.1.4/lib/polymer/polymer.html"></script> <link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.4/lib/paper-button/paper-button.html" /> <link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.4/lib/paper-checkbox/paper-checkbox.html" /> <dom-module is="wc-rnd-checkboxes"> <template> <paper-button on-click="handleRndGenerator" raised>Random Items</paper-button><br /><br /> <template is="dom-repeat" items="{{data}}"> <paper-checkbox></paper-checkbox> <span>{{index}}</span> <br /> </template> </template> </dom-module> <h3>Polymer Dom-repeat and paper-checkbox</h3> <p> <b>Instructions:</b> <ol> <li>click on the first checkbox;</li> <li>click on generate "Random Items";</li> <li>Issue: Polymer does not uncheck the first checkbox</li> </ol> </p> <wc-rnd-checkboxes></wc-rnd-checkboxes> 

http://jsfiddle.net/mprej0j4/70/

Before explaining why the checkboxes in the dom-repeat don't behave as you expect them to, let me point a couple of mistakes I found in your fiddle:

  1. polymer.html isn't a script so you should use an html import for it like this <link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.1.4/lib/polymer/polymer.html"> (I'm using polygit instead of rawgit in the example down below but it's the same thing)
  2. In order to push data into an array property that will be used for a dom-repeat you must use this.push("arrayProperty", pushedValue) or else the dom-repeat won't update. (Check the guide for more info on that)

Now, as for the problem with the checkboxes, the thing with dom-repeat is that it's pretty efficient, it updates lazily and only adds or removes elements when it's completely necessary (basically, when the size of the array changes), so it won't update the whole content of the template but only remove/add what's needed.

And that's exactly what's happening here, even if you're changing the array to a completely new one, since the dom-repeat only updates after you've finished populating data with its new values, it will only remove or add checkboxes depending on the new size of the array and update the data-bindings of the checkboxes that were already there to the new data .

That data-binding update is the crucial part, since there isn't any data-binding for the checkboxes checked property (or for any other property), every checkbox that wasn't removed will keep whatever state it was on before the data changed.

One way to achieve the behavior you want is to change the data array's structure and create data-bindings between the array items and the checkboxes' properties.

For example, I made it so the data array has this structure:

data = [{num: 1, checked: false}, {num: 2, checked: false}, {num: 3, checked: false}, {num: 4, checked: false}, {num: 5, checked: true}];

And the dom-repeat looks something like this:

<template is="dom-repeat" items="{{data}}">
    <paper-checkbox checked="{{item.checked}}"></paper-checkbox>
    <span>{{item.num}}</span>
    <br />
</template>

That way the checkboxes will be bound to the checked property of the corresponding element in the array.

Here's the fiddle where you can see everything working.

I hope this helped and didn't make you go tl;dr XD

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM