从观察到的数组中删除项目时,Polymer 2.0奇怪的行为

时间:2018-03-30 08:24:37

标签: javascript html polymer frontend polymer-2.x

在使用Polymer 2.0处理应用程序时,我遇到了这个简化代码所示的问题:https://jsfiddle.net/w912gf8g/33/

<base href="https://polygit.org/polymer+polymer+v2.0.0-rc.2/webcomponentsjs+webcomponents+:master/components/">

<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer-element.html">
<link rel="import" href="polymer/lib/elements/dom-repeat.html">

<root-element></root-element>

<dom-module id="root-element">
  <template>
    <dom-repeat items="[[items]]">
      <template>
        <inner-element inner=[[item]]></inner-element>
      </template>      
    </dom-repeat>   
    <button on-click="_removeItem">Remove the first item</button>
  </template>
</dom-module>

<dom-module id="inner-element">
  <template>
    <h3>Element: {{inner.prop}}</h3>
  </template>
</dom-module>

<script>
document.addEventListener('WebComponentsReady', () => {
    // Extend Polymer.Element base class
  class RootElement extends Polymer.Element {
  static get is() {
    return 'root-element';
  }

  constructor() {
    super();
  }

  static get properties() {
    return {
      items: {
        type: Array,
        value: () => [{ prop: 1 }, { prop: 2 }, { prop: 3 }],
        notify: true
      }
    }
  }

  _removeItem(){
    this.splice('items', 0, 1);
  }
}

// Register custom element definition using standard platform API
customElements.define(RootElement.is, RootElement);

class InnerElement extends Polymer.Element {
  static get is() {
    return 'inner-element';
  }

  constructor() {
    super();
  }

  static get properties() {
    return {
      inner: {
        type: Object,
        value: () => {},                            
        notify: true
      }
    }
  }

  static get observers() {
    return [
      '_changed(inner.prop)'
    ]
  }

  _changed(newVal){
    if(this.lastValue != null && this.lastValue !== newVal){
      alert("How on earth does this happen?");
    }

    this.lastValue = newVal;
  }
}

customElements.define(InnerElement.is, InnerElement);  
});
</script>

我希望在单击按钮后调用第一个元素的删除,调用警报消息的代码永远不应该运行,因为这表明数组条目的属性已被更改,这几乎没有感觉因为操作只是为了从数组中删除一个条目。

问题

为什么会这样?如何避免这种情况?我使用观察者或拼接方法的方式与设计使用的方式不同吗?

旁注

我可以猜出发生这种情况的原因是因为Polymer经过优化,实际上总是删除最后一个DOM元素并转移数据&#34;向上&#34;在那之前。

但我不明白这怎么可能不会在其他应用中引起重大副作用。

1 个答案:

答案 0 :(得分:0)

你必须在你的dom-repeat上添加mutable-data作为属性:

<template is="dom-repeat" items="[[data]]" mutable-data>

请查看此页面Data system concepts