有没有办法在 observable 的值变化时忽略订阅者。我想更改 observable 的值,但不为使用 Knockout.js 的订阅者执行它
在knockout.js 中更改可观察但不通知订阅者
通常这是不可能或不可取的,因为它可能会导致依赖链中的事物不同步。使用油门扩展器通常是限制依赖项接收通知数量的好方法。
但是,如果您真的想这样做,那么一种选择是notifySubscribers
在 observable 上覆盖该函数并让它检查一个标志。
这是一个将此功能添加到 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;
};
您可以将其添加到一个 observable 中,例如:
this.name = ko.observable("Bob").withPausing();
然后您可以通过执行以下操作在没有通知的情况下更新它:
this.name.sneakyUpdate("Ted");
一个更简单的方法:
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");
需谨慎使用。我们正在处理一个 observable 对象,因此如果您未能通知订阅者,可能会发生不好的事情。
当需要忽略所有订阅者时,我喜欢@RP Niemeyer提供的解决方案。但是,就我而言,我在 Select 控件上有一个带有 2 路绑定的 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
我来到这个问题是因为我正在构建一个分页数据网格。只显示了 10 行,每行都有一个复选框。表格标题有一个(取消)全选复选框。
在负载测试期间,我们发现单击全选复选框会导致一次更新 1000 个 observable。这花了太长时间。
看起来 KO 更新了 html 1000 次,即使只有 10 个 observables 绑定到 HTML。
如果有人出于同样的原因发现此问题,我建议您查看延迟更新。延迟更新队列通知订阅者,它会在您的“线程”完成后通知您的订阅者。每个 observable 或整个应用程序都可以配置延迟更新。