简体   繁体   English

聚合物,请遵守全局路径

[英]Polymer, observe global path, please

In Polymer 1.0 you can drop {{localPropFoo.bar}} and bar will be observed for changes if you use this.set('localPropFoo.bar', 'new value'); Polymer 1.0您可以放下{{localPropFoo.bar}} ,如果使用this.set('localPropFoo.bar', 'new value');将观察bar的变化this.set('localPropFoo.bar', 'new value'); to update its value. 更新其价值。

But what to do if you want to bind template to an external object which is out of your control? 但是,如果您要将模板绑定到无法控制的外部对象,该怎么办? Eg, this {{window.globalFoo.bar}} won't be bound to bar changes because external code doesn't depend on Polymer and doesn't call this.set . 例如,此{{window.globalFoo.bar}}不会受到bar变化的限制,因为外部代码不依赖于Polymer ,也不调用this.set

Demo on codepen Codepen上的演示

Using Object.observe manually requires extra code and doesn't work in FireFox (dirty checks of observe.js to the rescue). 手动使用Object.observe需要额外的代码,并且在FireFox中无法正常工作(对watch.js进行肮脏的检查以营救)。

I want to know what is the idiomatic way of data binding to external objects out of your control. 我想知道什么是超出您控制范围的将数据绑定到外部对象的惯用方式。

Polymer doesn't do observation out of the box, because: Polymer不会开箱即Polymer进行观察,因为:

  1. Object.observe support is not ubiquitous and dirty checks are expensive. Object.observe支持并非无处不在,脏检查很昂贵。
  2. Object.observe may be expensive on itself. Object.observe本身可能很昂贵。

Supposed Solution 假设的解决方案

Catch changes yourself, call notifyPath , this.fire('global-foo-changed', {path: 'globalFoo.bar', value:...} , this.set and this.push . 捕获更改自己,调用notifyPaththis.fire('global-foo-changed', {path: 'globalFoo.bar', value:...}this.setthis.push
They all dispatch corresponding non-bubbling (capturing) globalFoo-changed custom events (only when needed). 它们都调度相应的非冒泡(捕获) globalFoo-changed自定义事件(仅在需要时)。

Why my global-foo-changed events affect only this element? 为什么我的global-foo-changed事件仅影响this元素?

  1. global-foo-changed events are capturing (non-bubbling). global-foo-changed事件正在捕获(非冒泡)。
  2. Polymer elements listen for bubbling events by default. 默认情况下,聚合物元素侦听冒泡事件。
  3. For some reason these capturing listeners capture bubble events dispatched from the same element (not from its children). 由于某些原因,这些捕获侦听器捕获从同一元素(而不是从其子元素)调度的冒泡事件。 Demo on codepen . 在Codepen上的演示

You may patch polymer with this behavior ( I don't understand how it works ): 您可能会用这种行为修补聚合物( 我不知道它是如何工作的 ):

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);
  }
};

Why No Observation Out of the Box 为什么没有开箱即用的观察

...sometimes imperative code needs to change an object's sub- properties directly. ...有时命令性代码需要直接更改对象的子属性。 As we avoid more sophisticated observation mechanisms such as Object.observe or dirty-checking in order to achieve the best startup and runtime performance cross-platform for the most common use cases, changing an object's sub-properties directly requires cooperation from the user. 由于我们避免使用更复杂的观察机制(例如Object.observe或dirty-check)来针对最常见的用例实现最佳的启动和运行时性能跨平台,因此更改对象的子属性直接需要用户的配合。

Specifically, Polymer provides two methods that allow such changes to be notified to the system: notifyPath(path, value) and set(path, value), where path is a string identifying the path (relative to the host element). 具体来说,Polymer提供了两种方法,可将此类更改通知系统:notifyPath(path,value)和set(path,value),其中path是标识路径的字符串(相对于主机元素)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM