Question

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

Was it helpful?

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/

OTHER TIPS

You need to instantiate your view model with a statement like this:

var model = new BankViewModel();

When the model is instantiated, its computed methods are evaluated initially. This is where your alert will fire.

But, i assume you want your computed method to subscribe to Name, Code and Number properties. In this case, you need to read these properties at least once in your computed method.

This is how dependency tracking works in KO. It records all the observables that you mention in your computed function and logs them. And your computed is evaluated again when one of those observables are updated.

For your code up there, your computed will subscribe to FilterViewModel but not to its individual properties Name, Code and Number. So if you need to subscribe for the changes in these individual properties, you have to mention them individually in your computed function. Well, it wouldn't make sense to have your computed to subscribe to them if they don't affect your computed function anyway.

If you want to learn how the process works, please take a look at its documentation: http://knockoutjs.com/documentation/computedObservables.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top