Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent recursion with dependent observables

Tags:

knockout.js

I have an issue with my KnockoutJS code that is creating an infinite loop.

Say in my view model I have a value that represents the number of people going on a holiday. This value is bound to a select list, so that a customer can change the number of people.

var viewModel = {
    selectedTravellerCount:  ko.observable(),
    travellers: ko.observableArray([])       
}

When the value of the select list is changed (i.e. the quantity of travellers changes) I want to show an array of select lists to allow the customer to input the age of each traveller.

I assume that I need to create a observable dependent on the selectedTravellerCount that renders in the UI.

viewModel.travellerCount = ko.dependentObservable(function() {
    var tQ = this.selectedTravellerCount();
    alert("count:" + tQ);
        for (var i = 0; i < tQ; i++) {
        alert("adding");
        var t = new traveller();
        alert("a");
        t.Age = 18;
        alert("b");
        this.travellers.push(t);
        alert("added");
    }
}, viewModel);

This works OK when the page is first rendered. However, the first time the select list is changed, the dependentObservable function is repeatedly called and gets as far as the alert("b") line.

So, it looks to me that the traveller is being pushed to the travellers array, which is then causing function to run again, which then gets repeated ad infinitum.

However, I thought the function should only depend on the selectedTravellerCount value changing.

What am I missing?

I've also tried:

var viewModel = {
   selectedTravellerCount:  ko.observable(),
   travellers: ko.observableArray([])
   addTraveller: function (age) {
       alert(age);
       this.travellers.push({ age: age });
   }         
}

viewModel.travellerCount = ko.dependentObservable(function() {
    var tQ = this.selectedTravellerCount();
        for (var i = 0; i < tQ; i++) {
            this.addTraveller(18);
    }
}, viewModel);
like image 987
BrightonDev Avatar asked Feb 23 '26 00:02

BrightonDev


1 Answers

You need to use a subscription instead of dependsObservable(). A dependsObservable is triggered each time the viewModel changes, hence the name. Adding to the travellers == changing the viewModel

take a look here

Subscriptions are described here, at the bottom.

like image 198
Major Byte Avatar answered Feb 27 '26 09:02

Major Byte



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!