javascript - 如何正确通知聚合物中 sibling 之间的数据更改

标签 javascript polymer-1.0

我想要一个带有两个子元素的聚合物元素,一个子元素生成数据,另一个在数据更改时执行某些操作(在我的例子中:向服务器发送通知)。

为了实现这一点,我编写了一个聚合物元素,即 root,其结构如下(名称已更改以简化讨论):

<producer data={{foo.bar}}></producer>
<consumer data=[[foo]]></consumer>

生产者使用 set('property', 'value') 方法更改数据,以便 root 元素看到通知。问题是 consumer 元素不会注意到 foo 的更改,因为它们涉及子属性。

为了解决这个问题,我尝试使用 computed binding如下:

<producer data={{foo.bar}}></producer>
<consumer data=[[_compute(foo)]]></consumer>

...
_compute: function() {
    return this.foo;
}

但是,这不会导致消费者收到通知。我认为这样做的原因是返回的对象是相同的引用(仅更改了子属性)。目前我使用的解决方法是使用以下版本的 compute 函数:

_compute: function() {
    return Object.assign({}, this.foo);
}

这可行(consumer元素得到通知),但是我担心它可能不是最有效的(我在每次调用_compute时创建一个对象>) 和/或优雅的方式。那么我的问题是:在 Polymer 中实现这种行为的正确方法是什么?

最佳答案

您有权修改消费者元素吗?

解决此问题的最佳方法是让使用者元素具有多属性观察器,用于监听数据属性上的子属性更改。

它可能看起来像这样:

Polymer({
    is: 'consumer',
    properties: {
        data: Object
    },
    observers: ['consumeData(data, data.*)'],
    consumeData: function (data) {
        //Do whatever you were planning on doing with data here
    }
});

这样的方法的优点是,当数据对象的子属性发生变化时,您的“消费者”元素只是“知道”如何使用数据对象。由于 Polymer 中数据绑定(bind)的轻量级方法,尝试在“消费者”元素之外实现此行为必然会更昂贵且更复杂,因为它需要通过提供欺骗数据绑定(bind)认为数据对象是新的它使用对副本的新引用或完全放弃数据绑定(bind),并在事件之上构建方法并调用消费者的方法以响应事件。因此,如果可能的话,我建议尝试上述方法。

Polymer 的数据绑定(bind)的工作方式与其他一些支持双向的数据绑定(bind)实现不同,就像您在 AngularJS 中可能找到的那样。 Polymer 使用基于事件的“路径通知”方法,而不是使用极其昂贵的脏检查。当属性上的子属性更改时,具有该属性的 Polymer 元素将向绑定(bind)到该属性的直接子元素触发一个事件,通知它们路径“property.subProperty”已更改。为了让消费者对这些变化采取行动,必须告诉它沿着“property.subProperty”路径监听变化。我们使用上面的语法在聚合物观察器中指定路径。在这种情况下,将 data.* 放入观察者意味着我们想要监听数据的任何路径,以便数据属性上的任何通知属性更改都将触发观察者。

关于javascript - 如何正确通知聚合物中 sibling 之间的数据更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34786904/

相关文章:

javascript - Ionic 4 + HttpInterceptor + token

javascript - 删除 jQuery 中的动态表行不起作用

javascript - 通过计算绑定(bind)在 Polymer 中使用 dom-repeat 从 Firebase 动态获取文件 url

polymer 1.0 : How to pass an argument to a Polymer function from an attribute?

javascript - 如何在chart.js中显示每个切片的饼图数据值

javascript - jQuery。为什么它显示额外的元素?

javascript - 无法通过 setTimeout() 回调以编程方式显示 Bootstrap Vue 模式

javascript - Polymer.js 输入范围的默认参数

polymer - 使用 Polymer 在同一 Web 组件的实例之间进行通信的最佳方式?

javascript - 非自定义元素中的 Polymer-on-tap 处理程序