有没有办法忽略订阅者对可观察值的变化。我想改变一个observable的值,但不是为具有knockout.js的订阅者执行它
答案 0 :(得分:82)
通常这是不可能或不可取的,因为它可能会使依赖链中的内容不同步。使用节流扩展器通常是限制依赖关系接收的通知量的好方法。
但是,如果你真的想这样做,那么一个选项就是覆盖一个observable上的notifySubscribers
函数并让它检查一个标志。
这是一个将此功能添加到observable的扩展:
ko.observable.fn.withPausing = function() {
this.notifySubscribers = function() {
if (!this.pauseNotifications) {
ko.subscribable.fn.notifySubscribers.apply(this, arguments);
}
};
this.sneakyUpdate = function(newValue) {
this.pauseNotifications = true;
this(newValue);
this.pauseNotifications = false;
};
return this;
};
您可以将其添加到可观察的内容中:
this.name = ko.observable("Bob").withPausing();
然后你会在没有通知的情况下更新它:
this.name.sneakyUpdate("Ted");
答案 1 :(得分:14)
更简单的方法:
ko.observable.fn.silentUpdate = function(value) {
this.notifySubscribers = function() {};
this(value);
this.notifySubscribers = function() {
ko.subscribable.fn.notifySubscribers.apply(this, arguments);
};
};
按如下方式使用:
this.status = ko.observable("Happily Married");
this.walkIntoBar();
this.status.silentUpdate("Single");
this.walkOutOfBar(); // careful with exceptions
this.status.silentUpdate("Happily Married");
谨慎使用。我们正在处理一个可观察的对象,如果您未通知订阅者,可能会发生不好的事情。
答案 2 :(得分:6)
当所有订阅者都需要被忽略时,我喜欢 @RP Niemeyer 提供的解决方案。但是,对于我的情况,我在Select控件上有一个带有双向绑定的observable。使用 @RP Niemeyer 时,Select控件未更新。所以,我真的需要一种方法来关闭特定的观察者,而不是所有观察者。以下是此案例的一般化解决方案。
为“安静”添加扩展程序'订阅和安静'写入。
ko.observable.fn.ignorePokeSubscribe = function (callback, thisValue, event){
var self = this;
this.subscribe(function(newValue) {
if (!self.paused)
callback(newValue);
}, thisValue, event);
return this;
};
ko.observable.fn.poke = function (newValue) {
this.paused = true;
var result = this(newValue);
this.paused = undefined;
return result;
};
您可以订阅observable,如:
this.name = ko.observable("Bob");
this.name.ignorePokeSubscribe(function(newValue) { /* handler */ }));
然后您可以通过执行以下操作更新它而无需特定通知:
this.name.poke("Ted"); // standard subscribers still get notified
答案 3 :(得分:1)
我遇到了这个问题,因为我正在构建一个分页数据网格。仅显示了10行,每行都有一个复选框。表头有一个(de)select all复选框。
在加载测试期间,我们发现单击全选复选框导致一次更新1000个可观察对象。这花了太长时间。
似乎KO将html更新了1000次,尽管只有10个observable绑定到了HTML。
如果有人出于同样的原因发现了这个问题,我建议您查看延期更新。延期更新排队通知订阅者,它会在您的'线程后通知您的订阅者。已经完成了。延迟更新可根据可观察或整个应用程序进行配置。