Sonia Dhir
Sonia Dhir

Reputation: 41

How to stop firing observable on computed function in knockout js?

I am new to KnocoutJs. Any help is much appreciated. I want to call function on click of div and same function should be called inside computed function. Below is my function.

DetailViewModel.prototype.DisplayChange = function (name) {
    this.currentSelection(name);
    switch (this.currentSelection()) {
    case "abc":
        {
            this.abc();
            break;
        }
    case "xyz":
        {
            this.showxyz();
            break;
        }
    }
};

I am calling this function on click in .cshtml file and inside computed function.

<div class ="TestTabs" data-bind="foreach: availableTabs">
  <div class="Tab-ListItem" 
      data-bind="text: $data, click: $parent.DisplayChange.bind($parent), 
           css : {tabSelected : $parent.currentSelection() == $data}">
  </div>
</div>

And my computed:

this.selectedData = ko.computed(function () {
    return _this.compselectedData();
});

public compselectedData(): {
    this.DisplayChange(this.currentSelection())
}

Even When I call DisplayChange() on click, it is firing inside compselectedData(). How to stop firing computed function on click?

Upvotes: 1

Views: 667

Answers (1)

leszek.hanusz
leszek.hanusz

Reputation: 5317

You have an infinite loop:

  • The computed selectedData will always be reevaluated if the currentSelection is modified.
  • The currentSelection is modified inside the computed.

To break the loop, I suggest the following:

on the click event, change the currentSelection observable instead of calling the DisplayChange function:

<div class ="TestTabs" data-bind="foreach: availableTabs">
  <div class="Tab-ListItem" 
      data-bind="text: $data, click: $parent.currentSelection($data), 
           css : {tabSelected : $parent.currentSelection() == $data}">
  </div>
</div>

Don't change the observable in the DisplayChange function:

DetailViewModel.prototype.DisplayChange = function (name) {
    switch (this.currentSelection()) {
    case "abc":
        {
            this.abc();
            break;
        }
    case "xyz":
        {
            this.showxyz();
            break;
        }
    }
};

That is the beauty of knockout, you change only the model and the view is updated automatically.

Upvotes: 1

Related Questions