如何正确地通知聚合物中兄弟姐妹之间的数据变化
How to properly notify data changes between siblings in polymer
我想要一个包含两个子元素的聚合物元素,一个子元素生成数据,另一个子元素在数据更改时执行一些操作(在我的情况下:向服务器发送通知)。
为了实现这一点,我编写了一个聚合物元素,即root
,具有以下结构(更改名称以简化讨论):
<producer data={{foo.bar}}></producer>
<consumer data=[[foo]]></consumer>
生产者使用set('property', 'value')
方法更改数据,以便root
元素看到通知。问题是consumer
元素不会注意到对foo
的更改,因为它们涉及子属性。
为了解决这个问题,我尝试使用如下计算绑定:
<producer data={{foo.bar}}></producer>
<consumer data=[[_compute(foo)]]></consumer>
...
_compute: function() {
return this.foo;
}
但是,这不会导致通知consumer
。我认为这是因为返回的对象是相同的引用(只是更改了一个子属性)。目前,我使用的解决方法是使用以下版本的compute
函数:
_compute: function() {
return Object.assign({}, this.foo);
}
这是有效的(consumer
元素会得到通知),但我担心这可能不是最有效的(我在每次调用_compute
时都会创建一个对象)和/或优雅的方式。那么我的问题是:在聚合物中实现这种行为的正确方法是什么?
您有权修改consumer元素吗?
解决此问题的最佳方法是让consumer元素具有一个多属性观察器,用于侦听数据属性上的子属性更改。
它可能看起来像这样:
Polymer({
is: 'consumer',
properties: {
data: Object
},
observers: ['consumeData(data, data.*)'],
consumeData: function (data) {
//Do whatever you were planning on doing with data here
}
});
这种方法的优点是,当数据对象的子属性发生更改时,"consumer"元素只"知道"如何使用该数据对象。由于聚合物中数据绑定的方法重量较轻,尝试在"消费者"元素之外实现这种行为必然会更加昂贵和复杂,因为它需要通过向数据绑定提供对副本的新引用来欺骗数据绑定,使其认为数据对象是新的,或者完全放弃数据绑定,并在事件之上构建方法,并在消费者上调用方法来响应事件。因此,如果可能的话,我建议尝试上面的方法。
Polymer的数据绑定与其他一些双向数据绑定实现的工作方式不同,比如您可能在AngularJS中找到的。Polymer没有使用极其昂贵的脏检查,而是使用了基于事件的"路径通知"方法。当属性上的子属性发生更改时,具有该属性的Polymer元素将向绑定到该属性的直接子级激发事件,通知它们路径"property.subProperty"已更改。为了让消费者对这些变化采取行动,必须告诉它沿着"property.subProperty"路径倾听变化。我们通过使用上面的语法在聚合物观察器中指定路径。在这种情况下,将data.*放在我们的观测者中意味着我们想要监听数据的任何路径,这样,数据属性上任何通知的属性更改都会触发观测者。
正如您所注意到的,没有一种优雅的方法可以做到这一点。你让它工作的方式很有趣。
我期望的另一种工作方式是从生产者元素中激发事件。
this.fire('data', {data: this.foo.bar});
然后让父/根元素侦听此事件,然后更新消费者元素的数据属性。
<producer on-data="handleData"></producer>
<consumer id="consumer"></consumer>
handleData: function(e) {
self.$.consumer.data = e.detail.data;
}
编辑:
您可以创建一个新属性,在生产者元素中计算。然后,您就不必每次访问foo.bar 时都执行计算函数
生产者要素
properties: {
foo: {},
bar: {
computed: 'computeBar(foo)'
}
}
根元素:
<produce bar="{{bar}}"></producer>
<consumer data="[[bar]]"></consumer>
- 函数参数中的数据与指定变量之间的任何性能差异
- 在控制器和数据对象之间同步数据
- 使用服务(AngularJS)在控制器之间共享数据
- AngularJS中的页面之间共享数据返回空
- 通过共享服务在两个不同ng应用程序中的控制器之间共享数据
- Mongoose查询在两个日期时间之间提取数据
- 使用Angularjs在两个不同页面的控制器之间共享数据
- 使用JavaScript在网页之间进行数据传输
- 如何在网页之间存储数据
- 如何在Windows Phone 8.1应用程序中在C#和Javascript之间传递数据或通信
- 2ng控制器,并且需要在控制器之间共享数据
- 在控制器angular js之间共享数据
- 如何将json文件中的数据提取到对象数组中,并在两个控制器之间共享
- 基本html页面和弹出窗口之间的数据交换
- Meteor-在助手、事件和模板之间传递数据
- 如何在 Angularjs 中的交叉模块之间共享数据
- 在OnsenUI+AngularJS+PhoneGap中的控制器之间传递数据
- 最小化在javascript中客户端/服务器之间发送的数据
- 如果我在页面之间移动,Jquery 数据表行事件会卡住
- JavaScript:显示客户端和服务器之间数据传输的度量