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

时间:2021-09-23 20:37:57

Is there a way to ignore subscribers on a value change of the observable. Id like to change a value of an observable, but not execute it for the subscribers with knockout.js

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

4 个解决方案

#1


76  

Normally this is not possible or advisable, as it potentially allows things to get out of sync in the dependency chains. Using the throttle extender is generally a good way to limit the amount of notifications that dependencies are receiving.

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

However, if you really want to do this, then one option would be to overwrite the notifySubscribers function on an observable and have it check a flag.

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

Here is an extensions that adds this functionality to an 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;
};

You would add this to an observable like:

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

this.name = ko.observable("Bob").withPausing();

Then you would update it without notifications by doing:

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

this.name.sneakyUpdate("Ted");

#2


10  

An even simpler approach:

一种更简单的方法:

ko.observable.fn.silentUpdate = function(value) {
    this.notifySubscribers = function() {};
    this(value);
    this.notifySubscribers = function() {
        ko.subscribable.fn.notifySubscribers.apply(this, arguments);
    };
};

Use it as follows:

使用方法如下:

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

To be used with caution. We are dealing with an observable object so bad things can happen if you fail to notify your subscribers.

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

#3


5  

I like the solution provided by @RP Niemeyer when all subscribers need to be ignored. However, for my case, I have an observable with 2-way bindings on a Select control. When using @RP Niemeyer, the Select control isn't updated. So, I really needed a way to turn off specific observers, not all. Here is a generalized solution for this case.

当我需要忽略所有订户时,我喜欢@RP Niemeyer提供的解决方案。但是,对于我的情况,我在Select控件上有一个带有双向绑定的observable。使用@RP Niemeyer时,不会更新Select控件。所以,我真的需要一种方法来关闭特定的观察者,而不是所有观察者。这是这种情况的通用解决方案。

Add extensions methods for 'quiet' subscribe and 'quiet' writes.

为“安静”订阅和“安静”写入添加扩展方法。

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;
};

You would subscribe to observable like:

你会订阅observable,如:

this.name = ko.observable("Bob");
this.name.ignorePokeSubscribe(function(newValue) { /* handler */ }));

Then you would update it without specific notifications by doing:

然后,您可以通过执行以下操作更新它而无需特

this.name.poke("Ted");   // standard subscribers still get notified

#4


1  

I came to this question because I was building a paged datagrid. Only 10 rows were shown and each row has a checkbox. The table header had a (de)select all checkbox.

我来到这个问题是因为我正在构建一个分页数据网格。仅显示了10行,每行都有一个复选框。表头有一个(de)select all复选框。

During load tests we discovered that clicking the select all checkbox resulted in updating 1000 observables at once. This took way too long.

在加载测试期间,我们发现单击全选复选框导致一次更新1000个可观察对象。这花了太长时间。

It seemed that KO updated the html 1000 times even though only 10 observables were bound to HTML.

似乎KO更新了1000次html,尽管只有10个observable绑定到HTML。

If anyone finds this question for the same reason, I would suggest looking into deferred updates. Deferred updates queue notifying subscribers, it notifies your subscribers after your 'thread' is done. Deferred updates is configurable per observable or for your whole application.

如果有人出于同样的原因发现了这个问题,我建议调查延期更新。延迟更新队列通知订阅者,它会在您的“线程”完成后通知您的订阅者。延迟更新可根据可观察或整个应用程序进行配置。

http://knockoutjs.com/documentation/deferred-updates.html

http://knockoutjs.com/documentation/deferred-updates.html

#1


76  

Normally this is not possible or advisable, as it potentially allows things to get out of sync in the dependency chains. Using the throttle extender is generally a good way to limit the amount of notifications that dependencies are receiving.

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

However, if you really want to do this, then one option would be to overwrite the notifySubscribers function on an observable and have it check a flag.

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

Here is an extensions that adds this functionality to an 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;
};

You would add this to an observable like:

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

this.name = ko.observable("Bob").withPausing();

Then you would update it without notifications by doing:

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

this.name.sneakyUpdate("Ted");

#2


10  

An even simpler approach:

一种更简单的方法:

ko.observable.fn.silentUpdate = function(value) {
    this.notifySubscribers = function() {};
    this(value);
    this.notifySubscribers = function() {
        ko.subscribable.fn.notifySubscribers.apply(this, arguments);
    };
};

Use it as follows:

使用方法如下:

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

To be used with caution. We are dealing with an observable object so bad things can happen if you fail to notify your subscribers.

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

#3


5  

I like the solution provided by @RP Niemeyer when all subscribers need to be ignored. However, for my case, I have an observable with 2-way bindings on a Select control. When using @RP Niemeyer, the Select control isn't updated. So, I really needed a way to turn off specific observers, not all. Here is a generalized solution for this case.

当我需要忽略所有订户时,我喜欢@RP Niemeyer提供的解决方案。但是,对于我的情况,我在Select控件上有一个带有双向绑定的observable。使用@RP Niemeyer时,不会更新Select控件。所以,我真的需要一种方法来关闭特定的观察者,而不是所有观察者。这是这种情况的通用解决方案。

Add extensions methods for 'quiet' subscribe and 'quiet' writes.

为“安静”订阅和“安静”写入添加扩展方法。

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;
};

You would subscribe to observable like:

你会订阅observable,如:

this.name = ko.observable("Bob");
this.name.ignorePokeSubscribe(function(newValue) { /* handler */ }));

Then you would update it without specific notifications by doing:

然后,您可以通过执行以下操作更新它而无需特

this.name.poke("Ted");   // standard subscribers still get notified

#4


1  

I came to this question because I was building a paged datagrid. Only 10 rows were shown and each row has a checkbox. The table header had a (de)select all checkbox.

我来到这个问题是因为我正在构建一个分页数据网格。仅显示了10行,每行都有一个复选框。表头有一个(de)select all复选框。

During load tests we discovered that clicking the select all checkbox resulted in updating 1000 observables at once. This took way too long.

在加载测试期间,我们发现单击全选复选框导致一次更新1000个可观察对象。这花了太长时间。

It seemed that KO updated the html 1000 times even though only 10 observables were bound to HTML.

似乎KO更新了1000次html,尽管只有10个observable绑定到HTML。

If anyone finds this question for the same reason, I would suggest looking into deferred updates. Deferred updates queue notifying subscribers, it notifies your subscribers after your 'thread' is done. Deferred updates is configurable per observable or for your whole application.

如果有人出于同样的原因发现了这个问题,我建议调查延期更新。延迟更新队列通知订阅者,它会在您的“线程”完成后通知您的订阅者。延迟更新可根据可观察或整个应用程序进行配置。

http://knockoutjs.com/documentation/deferred-updates.html

http://knockoutjs.com/documentation/deferred-updates.html