JD Davis
JD Davis

Reputation: 3720

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.

Upvotes: 1

Views: 53

Answers (2)

JD Davis
JD Davis

Reputation: 3720

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

Upvotes: 0

user3297291
user3297291

Reputation: 23382

It's hard to tell without a concrete example, but I think you're looking for deferred updates.

You can extend an observable using .extend({ deferred: true })

Upvotes: 1

Related Questions