Polymer 1.x: Deleting an item from iron-list

2019-02-27 07:47发布

I am trying to delete an item from iron-list using the following code.

my-element.html
<iron-list id="list" items="[[items]]" as="item"
           selected-items="{{selectedItems}}"
           selection-enabled multi-selection>
  <template>
    <my-item item="[[item]]" on-tap="_onItemTap"></my-item>
  </template>
</iron-list>
...
_onItemTap: function(e) {
  this.items.splice(e.model.index, 1);
}

Expected behavior

  1. Tap list item
  2. List item disappears
  3. Select next list item
  4. Next list item is selected

Actual behavior

  1. Tap list item
  2. List item does not disappear
  3. Select same list item (i.e., the one previously intended to be deleted)
  4. Next list item is actually selected (i.e., index offset by one)

Questions

  • What code will result in the desired / expected behavior?
  • Please provide a working jsBin sample.

4条回答
我想做一个坏孩纸
2楼-- · 2019-02-27 07:59

This documentation on array mutation provides the following boilerplate code:

custom-element.html
<dom-module id="custom-element">
  <template>
    <template is="dom-repeat"></template>
  </template>
  <script>
    Polymer({
      is: 'custom-element',
      addUser: function(user) {
        this.push('users', user);
      },
      removeUser: function(user) {
        var index = this.users.indexOf(user);
        this.splice('users', index, 1);
      }
    });
  </script>
</dom-module>

Applying that to this case:

my-element.html
// As a syntactical matter, replace the following line
// this.items.splice(e.model.index, 1);
// With this line
this.splice('items', e.model.index, 1);
this.$.list.fire('resize');

A problem with this solution, however, is that it deletes the last item from the iron-list, not the item at the expected index. In other words, it behaves like one would expect this.items.pop().

It also throws the following curious error message:

console.log
Uncaught TypeError: <item> should be a valid item
查看更多
▲ chillily
3楼-- · 2019-02-27 08:09

See this answer for specific syntax contributing to the problem.

Here is a working JSBin.

http://jsbin.com/qefemoloxi/1/edit?html,console,output
<!doctype html>
<head>
  <meta charset="utf-8">
  <base href="https://polygit.org/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link href="polymer/polymer.html" rel="import">
  <link href="paper-button/paper-button.html" rel="import">
  <link href="iron-list/iron-list.html" rel="import">
</head>
<body>

<dom-module id="x-element">

<template>
  <style>
    iron-list {
      height: 100vh;
    }
  </style>
  <iron-list id="list" items="[[items]]" as="item">
    <template>
      <paper-button on-tap="_deleteItem">[[item.name]]</paper-button>
    </template>
  </iron-list>
</template>

<script>
  (function(){
    Polymer({
      is: "x-element",
      properties: {
        items: {
          type: Array,
          value: function() {
            return [
              { 'name':'foo' },
              { 'name':'bar' },
              { 'name':'qux' },
              { 'name':'baz' },
              { 'name':'quux'}
            ]
          }
        }
      },
      _deleteItem: function(e) {
        console.log(e.model.index);
        this.splice('items', e.model.index, 1);
        this.$.list.fire('resize');
      }
    });
  })();
</script>

</dom-module>

<x-element></x-element>

</body>
查看更多
我只想做你的唯一
4楼-- · 2019-02-27 08:16

A summary of this page suggests this documentation as follows:

Question
app.removeItem = function(index) {
  app.data.splice(index, 1);
  console.log("Removing " + index);
  document.querySelector('#tobuy').fire('resize');
};
Reply

document.querySelector('#tobuy').push('items', {name: "Foo"})

then you don't need to call resize.

ref: https://www.polymer-project.org/1.0/docs/devguide/properties.html#array-observation

查看更多
smile是对你的礼貌
5楼-- · 2019-02-27 08:19

See this answer for full code solution.

The problem here was caused by the fact that my item.html file was setting and displaying properties outside the item. property. So, when the iron-list.(this.)splice('items', e.model.index, 1); array mutation method was called, the non item properties were not being removed from the DOM.

Example:

my-list-item.html
this.set(     'name', this.item.foo.bar.qux); // This syntax caused the problem
this.set('item.name', this.item.foo.bar.qux); // This fixed the problem
my-iron-list.html
this.splice('items', e.model.index, 1);
查看更多
登录 后发表回答