Search code examples
javascriptjqueryknockout.jscomputed-observable

Knockout js Computed not being fired


The code can be found on http://jsfiddle.net/6kMWM/10/.

In the FilterViewModel I am creating an observable object.

var FilterViewModel=  ko.observable({
    Name: ko.observable("test"),
    Code: ko.observable("test"),
    Number: ko.observable("test")
});

Then in the BankViewModel I am running a computed method which when any of the input boxes change it should fire.

var BankViewModel = function(){
    var self = this;
        self.Collection = ko.observableArray([]),
        self.filteredCollection = ko.computed(function () {

            var filter = FilterViewModel();
            alert("invoked");
        }),
        self.add = function (bankObject) {
            self.Collection.push(bankObject);
        },
        self.isSelected = function (data) {
            $('.bank').css('background-color', 'white'); 
            $('.bank p').css('color', '#333');
            $('#bank-row-' + data.Code()).css('background-color', 'blue');
            $('#bank-row-' + data.Code()+" p").css('color', 'white');

        }
};

For some reason it is not being fired. Can any one help me out please.

Thank-you in advanced


Solution

  • There are several problems with your fiddle:

    1. You bind to values instead of observables. When you write <input type="text" data-bind="value: global.filterViewModel().Name()" placeholder="Filter by Name"/> ko uses the value of global.filterViewModel().Name not the observable. Thus there is no real binding (updating ko will not update the interface, updating the interface will not update ko). You need to remove the last parenthesis: global.filterViewModel().Name
    2. You put Name instead of Code and vice versa in the binding
    3. You subscribed to FilterViewModel's changes, but not it's child observable changes. To do this, include the evaluation of the child observables in your computed observable:

    -

    self.filteredCollection = ko.computed(function () {
        var filter = FilterViewModel();    
        if (filter.Name() != 'testname')
            alert("name");
        if (filter.Code() != 'testcode')
            alert("code");
        if (filter.Number() != 'testnumber')
            alert("number");
    }),
    

    You can test here http://jsfiddle.net/b37tu/1/