聚合物,请观察全球路径

时间:2015-09-12 11:20:40

标签: polymer globals object.observe

Polymer 1.0中,如果您使用{{localPropFoo.bar}}更新其值,则可以删除barthis.set('localPropFoo.bar', 'new value');,以便进行更改。

但是,如果要将模板绑定到不受控制的外部对象,该怎么办?例如,此{{window.globalFoo.bar}}不会受到bar更改的约束,因为外部代码不依赖Polymer且不会调用this.set

Demo on codepen

手动使用Object.observe需要额外的代码,并且无法在FireFox中工作(observe.js对救援的脏检查。)

我想知道数据绑定到外部对象的惯用方法是什么。

1 个答案:

答案 0 :(得分:0)

Polymer没有开箱即用的观察,因为:

  1. Object.observe支持无处不在,脏支票也很昂贵。
  2. Object.observe本身可能很贵。
  3. 提供解决方案

    自行更改,请致电notifyPaththis.fire('global-foo-changed', {path: 'globalFoo.bar', value:...}this.setthis.push
    他们都会调度相应的非冒泡(捕获)globalFoo-changed自定义事件(仅在需要时)。

    为什么我的global-foo-changed事件仅影响this元素?

    1. global-foo-changed事件正在捕获(非冒泡)。
    2. 默认情况下,聚合物元素会侦听冒泡事件。
    3. 由于某些原因,这些捕获侦听器捕获从同一元素(而不是其子元素)调度的冒泡事件。 Demo on codepen
    4. 你可以用这种行为修补聚合物(我不明白它是如何工作的):

      SharedGlobalsBehavior = {
        properties: {
          globalFoo: {
            type: Object,
            notify: true,
            value: globalFoo
          }
        },
        created: function() {
          window.addEventListener('global-foo-changed', () => {
            if (!event.detail || !event.detail.path)
              return; // Property initialization.
            this.notifyPath(event.detail.path, event.detail.value);
          },/* if capturing */ true);
        }
      };
      

      为什么没有开箱即用的观察

        

      ...有时候命令式代码需要直接更改对象的子属性。由于我们避免使用更复杂的观察机制(如Object.observe或脏检查)以便为最常见的用例实现跨平台的最佳启动和运行时性能,因此直接更改对象的子属性需要用户的协作。 / p>      

      具体来说,Polymer提供了两种方法,允许将这些更改通知给系统:notifyPath(path,value)和set(path,value),其中path是标识路径的字符串(相对于host元素)。