Saulis / iron-data-table

iron-data-table is a Web Component for displaying data as a table or grid. Built on top of iron-list using Polymer.
Apache License 2.0
147 stars 65 forks source link

Problem deleting and updating data #176

Open lluisgener opened 7 years ago

lluisgener commented 7 years ago

After deleting a row, all edits done to rows after the deleted one are not refreshed properly (usually don't refreshed at all, sometimes refreshing multiple rows (on some odd tests I did), or refreshing the last row when trying to update the penultimate).

The code:

<dom-module id="x-table">
    <template>
        <style>
        </style>
        <iron-data-table id="idt" items="{{model.Test}}">
            <data-table-column name="Name" filter-by="Name" sort-by="Name">
                <template>[[item.Name]]</template>
            </data-table-column>
            <data-table-column flex="0" align="right">
                <template>
                    <iron-icon icon="icons:create" on-tap="_edit"></iron-icon>
                </template>
            </data-table-column>
            <data-table-column flex="0" align="right">
                <template>
                    <iron-icon icon="icons:delete" on-tap="_delete"></iron-icon>
                </template>
            </data-table-column>
        </iron-data-table>

       <!-- <iron-list items="{{model.Test}}" id="idt">
            <template>
                <div class="item">
                    {{item.Name}}
                    <iron-icon icon="icons:create" on-tap="_edit"></iron-icon>
                    <iron-icon icon="icons:delete" on-tap="_delete"></iron-icon>
                </div>
            </template>
        </iron-list>-->

    </template>

    <script>
        XTable = Polymer({
            is: 'x-table',
            ready: function() {
               //Initialize table with 10 rows
                var max = 10;
                var x = [];

                for(var i = 1; i < max; i++) {
                    var o = {
                        Name: "" + i
                    };

                    x.push(o);
                }

                this.model = {};
                this.set("model.Test", x);
            },
            _edit: function(template) {
                //edit the selected row name with a random value

                var x = template.model.item;
                var idx = this.model.Test.indexOf(x);

                this.set("model.Test." + idx + ".Name", Math.random());
            },
            _delete: function(template) {
                //delete the selected row

                var x = template.model.item;
                var idx = template.model.index;
                this.splice("model.Test", idx, 1);
            }
        });
    </script>
</dom-module>

Steps to reproduce:

Click edit on first row (for example). You can see the name is updated Click delete on second row (for example). You can see the row is deleted Click edit on any row. You can see nothing happens, unless it's the first row, or the penultimate.

There is a commented iron-list to check if the issue was with the inner iron-list or the iron-data-table. You can see that iron-list doesn't have this issue.

Saulis commented 7 years ago

Well this is really strange, thanks for the report!

lluisgener commented 7 years ago

I can see that, after the deletion, when _itemsChanged is called, there is a problem retrieving the correct index. I think that you can't rely on the items.# index, because I think it's the internal key polymer uses in the original array and it no longer matches the correct element.

Even though, I tried to modify the index to the correct one while debugging, and still no luck.

lluisgener commented 7 years ago

I think you can improve the index/item detection part with the following code:

          //var index = items.path.split('.')[1].substring(1);
          //var item = this.items[index];

          var index = items.path.split('.')[1];
          var col = Polymer.Collection.get(items.base);
          var item = col.getItem(index);

Please note that this doesn't fix the issue, but I think it fixes the bad index retrieval.

Also, I'm pretty sure the bug is related to the _cachedItems array. If I replace the binding in the iron-list with "items", the edit/delete bug is fixed... But obviously, filtering, and many other things get broken.

lluisgener commented 7 years ago

I think I have managed to fix the problem. I am not sure if it may have some side effects, or performance is degraded in any way. It seems to work, even with filtering, sorting, etc...

Also, I have added two lines to try to restore scroll position when a _resetData is invoked.

I have attached two files:

iron-data-table.html.txt --> the fixes are marked with LGE test-iron-data-table.html.txt --> test file to compare iron-data-table with iron-list and see if they go out of sync

test-iron-data-table.html.txt

iron-data-table.html.txt