阵列突变而不触发特定的观察者
Array mutation without triggering a specific observer
我正在使用web套接字将属性boardBucket
的更改传输到其他客户端。
-
CCD_ 2是由观察者观察的CCD_ 3类型的共享属性。
-
当观测者收到更改通知时,这些更改将通过套接字发送到其他客户端,在那里它们将应用于自己的
boardBucket
。
现在的问题变成了如何防止某些对象更改(通过数组突变方法this.set()
、this.push()
等)重新触发发送更改的特定观察者。
如果没有某种静音功能,整个设置将在客户端之间进行无限的往返(一个客户端更改boardBucket
,另一个客户端应用更改,但这也会触发它自己的boardBucket
观察器,并不断重新发送)。
是否可以在不以某种方式触发特定观察者的情况下更改属性(或其任何子项)的值?
properties: {
boardBucket: {
type: Object,
value: null,
notify: true
}
},
observers: [
"_boardBucketChanged(boardBucket.*)"
],
// if my `boardBucket` changes send changes to other clients
_boardBucketChanged: function(changes) {
sockets.send(changes);
},
// get changes sent by other clients and apply them
_boardBucketReceived: function(changes) {
// How can I silently make the following changes
// so it doesn't trigger **only** the above observer?
this.set("boardBucket", changes);
}
理想情况下,当对象/数组发生变化时,可以传递一个标志,该标志可以在观察器中拾取,如下所示:
// flag can be read in observer
_boardBucketChanged: function(changes, flag) {
if(flag === "preventNotify") return false;
sockets.send(changes);
},
// `flag` parameter can be passed with each mutation
_boardBucketReceived: function(changes) {
if(flag === "preventNotify")
return false;
this.set("boardBucket", changes, "preventNotify");
}
注意:
- 我也可以使用
<iron-signals>
(即事件)来代替观察者,但我更喜欢避免它们,因此产生了这个问题 boardBucket
是多个内部组件共享的属性,每个组件都会发生变化并观察到这一点。这就是我问在变异时是否只有特定的观察者可以跳过的原因- 我可以在传入/传出更改之间进行一些相等性检查,如果
changes
的路径/值相同,则忽略它而不发送它。但是,我希望有一种方法可以防止其他一些突变到达套接字发送函数,因此这不起作用。这也有点古怪
我很想知道如果你做这样的事情会发生什么:
properties: {
boardBucket: {
type: Object,
value: null,
notify: true
},
settingBucket: {
type: Boolean,
value: false
}
},
observers: [
"_boardBucketChanged(boardBucket.*)"
],
// if my `boardBucket` changes send changes to other clients
_boardBucketChanged: function(changes) {
//If we're setting, this is our change.
//TODO: Is there any way that we can receive a change while
//setting that is NOT the result of calling this.set? For
//example if changes are batched and sent at once?
if (!this.settingBucket) sockets.send(changes);
},
// get changes sent by other clients and apply them
_boardBucketReceived: function(changes) {
//We are currently setting bucket, so ignore received changes
this.settingBucket = true;
this.set("boardBucket", changes);
//Now we're done
this.settingBucket = false;
}
这似乎也有点棘手,我对这种方法的局限性的理解如下:
如果(并且仅当)this.set
在返回之前准确地传递了传递给它的更改,那么这应该有效。如果它传递更多的更改,或者传递异步传递的更改,那么这将不起作用。查看我们拥有的Polymer变更通知协议文档:
当属性更改时,元素会触发一个非冒泡DOM事件,将这些更改指示给感兴趣的主机。
如果使用了DOM事件,我认为应该在this.set
调用返回之前交付它。
因此,我认为出现这种问题的唯一机制是,如果有人在听boardbucket的话,决定对你的更改做出更改——我想你应该控制你的应用程序,而且在任何情况下,这似乎都是一件坏事。如果发生这种情况,我看不出任何回应是有效的;要么忽略这些"响应更改而进行的更改",boardbucket在客户端之间变得不同步,要么通过套接字发送它们,然后返回到潜在的循环。
更详细地说,如果我们将响应更改的更改称为更改^2,那么代码只会阻止将更改^2发送到套接字。如果更改^2对其他客户没有意义,那么这是正确的行为。如果更改^2对其他客户端有意义,那么我想它们需要被发送到套接字,但这将是低效的,因为它使用通过网络的循环来更新数据,而这种方式可能不是对用户输入的响应。我想这样的更改^2最好由看到原始更改的客户端进行——它可以计算出需要^2对将要发送的现有更改进行哪些更改,并将其添加到中以一次性发送。这样只需要一次网络传输,并且任何接收客户端都知道数据是有效的,不会触发任何更改^2。
- 检测 DIV 的高度何时变化,而无需轮询或突变观察者
- 突变观察者尚未定义
- 突变观察者未能检测到元素's删除dom
- 手动调整元素大小;不要在Chrome中激发突变观察者
- 未捕获的类型错误:无法执行'观察'在'突变观察者':参数1不是'节点'
- 阵列突变而不触发特定的观察者
- 突变观察者收到的突变记录的顺序是什么?
- 突变观察者 - 未检测到添加的某些节点
- 使用突变观察者将 DOM 元素列入黑名单
- 突变观察者仅获取特定内容
- 重新连接并断开突变观察者
- 突变观察者不起作用
- DOM突变观察者:如何支持DOM3突变事件的一个重要用途
- 突变观察者字符数据使用情况,没有子列表
- 突变观察者不检测文本变化
- 使突变观察者更快,资源更少
- 聚合物:用复杂观察者观察阵列突变
- 铬突变观察者
- Firefox不遵守突变观察者的childList配置参数
- 如何使用突变观察者对特定的样式属性更改做出反应