更改可观察但不通知knockout.js中的订阅者

Mik*_*ynn 43 javascript events knockout.js

有没有办法忽略订阅者对可观察值的变化.我喜欢更改observable的值,但不为具有knockout.js的订阅者执行它

RP *_*yer 82

通常这是不可能或不可取的,因为它可能允许事物在依赖链中失去同步.使用节流扩展器通常是限制依赖关系接收的通知量的好方法.

但是,如果你真的想这样做,那么一个选项是覆盖notifySubscribersobservable上的函数并让它检查一个标志.

以下是将此功能添加到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;
};
Run Code Online (Sandbox Code Playgroud)

你可以将它添加到一个observable,如:

this.name = ko.observable("Bob").withPausing();
Run Code Online (Sandbox Code Playgroud)

然后你会通过这样做更新它而不通知:

this.name.sneakyUpdate("Ted");
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,最适合暂停通知,以便您可以更新所有可观察对象并仅在最后触发订阅(ryan的帖子http://www.knockmeout.net/2011/04/pausing-notifications-in -knockoutjs.html) (3认同)
  • 限制+1.我想避免在设置计算所依赖的多个observable时多次运行计算.结果:速度++ (2认同)
  • 很好的答案.我认为'sneakyUpdate'可以更好地命名为'poke',因为KO提供了一种内置的'peek'方法,它可以完全读取.'poke'将是'peek'的可写版本. (2认同)

Ste*_*las 14

一种更简单的方法:

ko.observable.fn.silentUpdate = function(value) {
    this.notifySubscribers = function() {};
    this(value);
    this.notifySubscribers = function() {
        ko.subscribable.fn.notifySubscribers.apply(this, arguments);
    };
};
Run Code Online (Sandbox Code Playgroud)

使用方法如下:

this.status = ko.observable("Happily Married");
this.walkIntoBar();
this.status.silentUpdate("Single");
this.walkOutOfBar(); // careful with exceptions
this.status.silentUpdate("Happily Married");
Run Code Online (Sandbox Code Playgroud)

谨慎使用.我们正在处理一个可观察的对象,如果您未通知订阅者,可能会发生不好的事情.

  • 再加上一个或创意示例! (4认同)

rai*_*r33 7

我喜欢@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;
};
Run Code Online (Sandbox Code Playgroud)

你会订阅observable,如:

this.name = ko.observable("Bob");
this.name.ignorePokeSubscribe(function(newValue) { /* handler */ }));
Run Code Online (Sandbox Code Playgroud)

然后你会通过这样做更新它而不需要特定的通知:

this.name.poke("Ted");   // standard subscribers still get notified
Run Code Online (Sandbox Code Playgroud)

  • 我认为这并不意味着你的意思. (2认同)