【问题标题】:Polymer, observe global path, please聚合物,请观察全局路径
【发布时间】:2015-12-08 21:13:48
【问题描述】:

Polymer 1.0 中,您可以删除{{localPropFoo.bar}},如果您使用this.set('localPropFoo.bar', 'new value'); 更新其值,将观察bar 的变化。

但是,如果您想将模板绑定到您无法控制的外部对象,该怎么办?例如,这个 {{window.globalFoo.bar}} 不会绑定到 bar 更改,因为外部代码不依赖于 Polymer 并且不调用 this.set

Demo on codepen

手动使用 Object.observe 需要额外的代码,并且在 FireFox 中不起作用(对 observe.js 进行脏检查以进行救援)。

我想知道将数据绑定到您无法控制的外部对象的惯用方式是什么。

【问题讨论】:

  • 你试过铁信号吗?它可以监听任何 Iron-signal-* 事件,无论其在 DOM 中的位置如何。
  • 惯用方式是不要绑定到您无法控制的外部对象。您是否使用其他设置它的库?如果您控制整个应用程序,那么应该不需要它。
  • observe-js 是你这里唯一的帮手,但它是笨拙的方法
  • @Andrey 我使用自己的库,我不想依赖 Polymer,但我可以让它以某种方式发出事件,也许是 Node 的 EventEmitter
  • @ilyaigpetrov 你可以使用原生 JS 事件

标签: polymer globals object.observe


【解决方案1】:

Polymer 不进行开箱即用的观察,因为:

  1. Object.observe 支持并不普遍,脏检查很昂贵。
  2. Object.observe 本身可能很昂贵。

假设的解决方案

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

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

  1. global-foo-changed 事件正在捕获(非冒泡)。
  2. Polymer 元素默认监听冒泡事件。
  3. 出于某种原因,这些捕获侦听器捕获从同一元素(而不是从其子元素)调度的气泡事件。 Demo on codepen

你可以用这种行为修补聚合物(我不明白它是如何工作的):

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 或脏检查,以便为最常见的用例实现跨平台的最佳启动和运行时性能,因此直接更改对象的子属性需要用户的配合。

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

【讨论】:

    猜你喜欢
    • 2014-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-10
    • 2017-10-03
    • 1970-01-01
    • 1970-01-01
    • 2018-11-21
    相关资源
    最近更新 更多