如何观察数组或对象中任何属性的更改?

时间:2014-03-09 03:27:42

标签: javascript polymer

我想做这样的事情

    Polymer('bc-datalist', {
        listitems: [
            {name: 'item1'},
            {name: 'item2'}
        ],
        observe: {
            'listitems': 'change'
        },
        change: function () {
            // do something
        }
    });

这不起作用,所以我的工作是做这样的事情:

    Polymer('bc-datalist', {
        listitems: {
            1:{name: 'item1'},
            2:{name: 'item2'}
        },
        observe: {
            'listitems.1.name': 'change',
            'listitems.2.name': 'change'
        },
        change: function () {
            // do something
        }
    });

当对象/数组项发生变化时,有没有办法注册回调?

3 个答案:

答案 0 :(得分:2)

如果我错了,请纠正我,但看起来你的第一个例子中有一个拼写错误。如果您要将listitems作为要观察的对象,请改为引用listitem。将此更改为listitems将使普通顶级属性的工作正常:

<polymer-element name="test-el">
  <template>
    <button on-click="{{clickHandler}}">Click me</button>
  </template>
  <script>
    Polymer('test-el', {
        listitems: [
            {name: 'item1'},
            {name: 'item2'}
        ],
        observe: {
            'listitems': 'change'
        },
        change: function () {
            // do something
            alert('listitems changed!');
        },
        clickHandler: function(){
          this.listitems.push({ name: 'item3'});
        }
    });
</script>
</polymer-element>

在您的问题上:就我所知,Polymer不会为观察块中包含的属性调用propertyNameChanged回调。这意味着您需要为您要观察的内容指定确切的嵌套对象路径(a.b.c),或手动手动设置相关类型的Path / Compound观察器:https://github.com/Polymer/observe-js

答案 1 :(得分:2)

Polymer observe-js库支持对对象的路径观察以及array observation。前者可以与您的设置类似(参见2nd example in the docs)。

Polymer('x-element', {
  observe: {
    'a.b.c': 'validateSubPath'
  },
  ready: function() {
    this.a = {
      b: {
        c: 'exists'
      }
    };
  },
  validateSubPath: function(oldValue, newValue) {
    var value = Path.get('a.b.c').getValueFrom(this);
    // oldValue == undefined
    // newValue == value == this.a.b.c === 'exists'
  }
});

我正在检查ArrayObserver支持。当我知道更多时,会更新这篇文章。

答案 2 :(得分:1)

如果您有一个对象数组,并希望观察对这些对象的任何属性所做的更改,则可以尝试自定义元素<observe-array-items>。它简化了为数组中的所有对象创建单个PathObserver的过程,并在列表中添加/删除项目时对其进行维护。

在您的示例中,您可以执行类似

的操作
<polymer-element name="test-el">
  <template>
    <observe-array-items array="{{listitems}}"
                         path="name"
                         on-array-item-changed="{{handleNameChanged}}">
    </observe-array-items>
  </template>
  <script>
    Polymer({
        listitems: [
            {name: 'item1'},
            {name: 'item2'}
        ],
        handleNameChanged: function (e) {
          // This will be called whenever the 'name' property
          //   of an existing object in listitems changes.
          // e.detail.oldValue and e.detail.newValue will
          //   contain the old and current values
          // e.detail.index will correspond to the index of the object in the array.
        },
        listitemsChanged: function() {
          // This will be called whenever an object is added or removed from listitems
        }
    });
  </script>
</polymer-element>