如何观察 Polymer 的 sub-属性 变化?

How do I observe sub-property changes in Polymer?

对于这个对象:

obj = {
        a:'a value',
        b:'b value'
      }

每当 ab 的值发生变化时,我都需要调用一个函数。 我看到了 Observe changes for an object in Polymer JS,但该解决方案对我不起作用。

我尝试添加这样的观察者失败:

 observers: [
    'abc(obj.*)' //abc is function which need to be called
 ]

和:

 observe: {
    'obj.a': 'abc'     // here I'm observing a's attribute
 },

笨蛋: http://plnkr.co/edit/BvX25wJHJh7i2aeyVBks?p=preview

在您的 Plunker 中,在 ready() 回调中更改 obj.a 后不会调用观察者,因为子属性是直接分配的,不会自动为观察者触发更改事件(或数据绑定)来查看。这是更正后的 plunker.

Polymer 文档描述了如何 observe subproperty changes:

In order for Polymer to properly detect the sub-property change, the sub-property must be updated in one of the following two ways:

还有第三种方式:调用notifyPath.

this.obj.a 进行更改后,您可以通过调用 this.notifyPath('obj.a', this.obj.a):

通知观察者并更新绑定
this.obj.a = 100;
this.obj.a++;
this.notifyPath('obj.a', this.obj.a);

HTMLImports.whenReady(() => {
  Polymer({
    is: 'x-foo',
    properties: {
      obj: {
        type: Object,
        value: () => ({a: 1, b: 2})
      }
    },
    observers: [
      '_objChanged(obj.a, obj.b)'
    ],
    _objChanged: function(a, b) {
      console.log('a', a, 'b', b);
    },
    _doNotifyPath: function() {
      this.obj.a++;
      this.obj.b++;
      this.notifyPath('obj.a', this.obj.a);
      this.notifyPath('obj.b', this.obj.b);
    }
  });
});
<head>
  <base href="https://polygit.org/polymer+1.11.3/components/">
  <script src="webcomponentsjs/webcomponents-lite.js"></script>
  <link rel="import" href="polymer/polymer.html">
</head>
<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <template>
      <div>obj.a = [[obj.a]]</div>
      <div>obj.b = [[obj.b]]</div>
      <button on-tap="_doNotifyPath">Notify Path</button>
    </template>
  </dom-module>
</body>

或者,您可以将设置和通知与 this.set('obj.a', 'new value') 结合使用:

this.set('obj.a', this.obj.a + 1);

HTMLImports.whenReady(() => {
  Polymer({
    is: 'x-foo',
    properties: {
      obj: {
        type: Object,
        value: () => ({a: 1, b: 2})
      }
    },
    observers: [
      '_objChanged(obj.a, obj.b)'
    ],
    _objChanged: function(a, b) {
      console.log('a', a, 'b', b);
    },
    _doSet: function() {
      this.set('obj.a', this.obj.a + 1);
      this.set('obj.b', this.obj.b + 1);
    }
  });
});
<head>
  <base href="https://polygit.org/polymer+1.11.3/components/">
  <script src="webcomponentsjs/webcomponents-lite.js"></script>
  <link rel="import" href="polymer/polymer.html">
</head>
<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <template>
      <div>obj.a = [[obj.a]]</div>
      <div>obj.b = [[obj.b]]</div>
      <button on-tap="_doSet">Set</button>
    </template>
  </dom-module>
</body>

codepen