【问题标题】:Adding an item to array does not re-render polymer template将项目添加到数组不会重新渲染聚合物模板
【发布时间】:2017-08-26 05:58:33
【问题描述】:

我正在尝试使用 dom-repeat 的模板来呈现项目的动态列表,如下所示:

<template is="dom-repeat" items={{numbers}} as="anumber" >
  <div>
    {{anumber}}
    <paper-button class="deleteThisNumber" index={{index}}></paper-button>
  </div>
</template>
<paper-button id="addNumber"></paper-button>

每个项目都有一个用于删除该项目的按钮。

dom-repeat 模板的外部 按钮也尝试向数组numbers 添加条目。 JS 看起来是这样的:

Polymer ({

is: "something",

properties: {
    numbers: {
        type: Array,
        value: ["1"]
    }
},
removeByIndex: function (array, index) {
    return array.filter(function (elem, _index) {
        return index != _index;
    });
},
attached: function () {
    var myself = this;
    $(this).on('click', '.deleteThisNumber', {}, function (e) {
        myself.numbers = myself.removeByIndex(myself.numbers, this.index)
    });
    this.$.addNumber.addEventListener("click", function (e) {
        myself.numbers.push("123");
    })
},
...
});

结果是:删除有效,添加无效。

通过说“有效”,我的意思是该列表通过添加/删除 DOM 中的条目来反映更改。我检查了numbers 属性,它一直被正确修改。那么,如果更改是添加(array.push),为什么 Polymer 不会将数组属性的更改反映到模板?我应该如何解决这个问题? (除了手动添加 div 之外,我愿意接受任何建议。)

我的 Polymer 版本是 1.X

【问题讨论】:

    标签: javascript polymer


    【解决方案1】:

    将数组推送的代码改为:

        this.$.addNumber.addEventListener("click", function(e) {
          myself.push("numbers", "123");
        })
    

    为了呈现更新的属性或子属性,必须有一个可观察到的变化可观察到的变化Polymer 可以与路径关联的数据变化。

    如果您使用本机方法(如Array.prototype.push)操作数组,则必须在事后通知 Polymer。或者,使用 Polymer 方法进行数组突变。

    修改数组时,提供了一组数组变异方法 模仿Array.prototype 方法的聚合物元素原型,具有 他们将path 字符串作为第一个参数的例外。这 path 参数标识要变异的元素上的数组,其中 以下参数与本机 Array 方法的参数匹配。

    这些方法对数组执行突变动作,然后 通知可能绑定到同一数组的其他元素 变化。在改变数组时必须使用这些方法以确保 观察数组的任何元素(通过观察者,计算 属性或数据绑定)保持同步。

    每个 Polymer 元素都有以下数组变异方法 可用:

    push(path, item1, [..., itemN]) 
    pop(path) 
    unshift(path, item1, [...,
    itemN])
    shift(path)
    splice(path, index, removeCount, [item1, ..., itemN])
    

    Learn More

    【讨论】:

    • 这很好用!你能解释一下为什么我可以向 Polymer dom 调用 push 函数吗?
    • 感谢您的解释。我发现这种方法和我在下面找到的解决方案都有一个问题:如果我删除一些项目并添加更多项目,特别是当我删除数组中间的项目时,就会发生数据绑定问题:一些条目的数据在数组中绑定在一起。你遇到过类似的问题吗?
    • 如果您将删除更改为使用 myself.splice 执行项目的就地删除而不创建新数组,您应该没有任何问题。如果你这样做,就不需要 notifyPath。
    • 太棒了! myself.splice 有效。但是myself.push 仍然会导致多个条目中的数据绑定在一起。可以这么说,我将使用myself.splice 进行删除,并在下面使用我的答案进行添加。谢谢
    【解决方案2】:

    我发现解决方案是强制通知路径多一点:

    myself.numbers.push("123"); //before only has this
    myself.notifyPath('numbers', myself.numbers.slice()); //added
    

    参考https://github.com/Polymer/polymer/issues/2068#issuecomment-120767748

    @miyconst 的回答

    【讨论】:

      【解决方案3】:

      修复代码的方法不止一种。

      1) 删除项目时已使用的方式。

      this.$.addNumber.addEventListener("click", function (e) {
          myself.numbers.push("123");
          myself.numbers = myself.numbers.slice();
      })
      

      2) 自己回答(略有变化)

      this.$.addNumber.addEventListener("click", function (e) {
          myself.numbers.push("123");
          myself.notifyPath("numbers");
      })
      

      3) 来自@Ofisora 的回答

      this.$.addNumber.addEventListener("click", function(e) {
          myself.push("numbers", "123");
      })
      

      这就是修复工作的原因,https://www.polymer-project.org/1.0/docs/devguide/data-system#observable-changes

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-29
        • 1970-01-01
        • 2018-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多