Jdsfighter Jdsfighter - 1 month ago 18
Javascript Question

Update multiple subscribables, but only execute update once in knockout?

I have an application that has several knockout components. The knockout components are all bound to a set of subscribables that update on a button click. Each component has several subscribe functions listening for subscriber changes to call an update function contained within them.

How can I configure them to only call their update function once when multiple subscribers have been updated?

Here is a sample snippet of how most of my components load:

this.OBSERVABLE_NAME.subscribe(function () { this.updateChart(); }, this);
this.OBSERVABLE_NAME.subscribe(function () { this.updateChart(); }, this);
this.OBSERVABLE_NAME.subscribe(function () { this.updateChart(); }, this);
this.OBSERVABLE_NAME.subscribe(function () { this.updateChart(); }, this);

this.updateChart = function () {
$.ajax({
type: "POST",
traditional: true,
url: this.ajax_location,
data: this.ajax_parameters,
success: function (data) {
// DO SOMETHING
}.bind(this),
error: function (returndata) {
alert("Error:\n" + returndata.responseText);
}
});
};


However, if I replace the subscribe functions with:

ko.computed(function () {
$.ajax({
type: "POST",
traditional: true,
url: this.ajax_location,
data: this.ajax_parameters,
success: function (data) {
// DO SOMETHING
}.bind(this),
error: function (returndata) {
alert("Error:\n" + returndata.responseText);
}
});
}, this).extend({ throttle: 1 });


It seems to work as requested. I know throttle is depreciated, but I'm curious why deferred doesn't seem to work properly.

Answer

It looks like this is a good use for throttling or deferred updates. In my case, deferred didn't seem to work properly, but throttling it did. I use the following snippet:

ko.computed(function () {
        $.ajax({
        type: "POST",
        traditional: true,
        url: this.ajax_location,
        data: this.ajax_parameters,
        success: function (data) {
            // DO SOMETHING
        }.bind(this),
        error: function (returndata) {
            alert("Error:\n" + returndata.responseText);
        }
    });
}, this).extend({ throttle: 1 });
Comments