AntouanK
AntouanK

Reputation: 4988

Knockoutjs trigger function when text changes

I have a viewmodel that is populated every few seconds by a json request.

viewModel = ko.mapping.fromJS([]);
...
getJSON(){
    ...
    ko.mapping.fromJS(data,viewModel);
}

Then I have some text bindings in the HTML.

<div id="mainContainer" data-bind='foreach: viewModel'>
    <span data-bind='text: name()'></span>
    <!-- ko foreach: items() -->
        <span data-bind='text: value()'></span>
    <!-- /ko -->
</div>

Normally, these values are changed every 1-2 minutes. But with every JSON read, the model is 'updated' and thinks that all the values are 'new'. So I cannot use 'update'. Let's say I want to do something when this value really changes. For example have a green border for 2 seconds. Is there a way to evaluate the values every time the model is updated and check for each one if the old value is different from the new one?

Another problem is that the data I get is an array with objects inside. [ { name: 'name1', items:[ {},{} ]} , { name: 'name2', items:[ {},{}] }, ... ]

So, ko.mapping.fromJS(data), returns [ ] !! Had to use ko.mapping.fromJS(data, {}, viewModel); , but I don't know if it's the same...

Upvotes: 0

Views: 185

Answers (1)

Christoffer
Christoffer

Reputation: 2125

You should use a mapping when you first create your viewModel. The mapping lets you specify which property to use as the unique key, preventing unnecessary removal/inserts of objects in the array.

Please read the section called Uniquely identifying objects using “keys” in the ko.mapping docs: http://knockoutjs.com/documentation/plugins-mapping.html

If you have more complex objects with arrays deeper than the root level, you will need specify a mapping at all places where you want to specify a unique key. Here's an example (jsfiddle with sample data here: http://jsfiddle.net/9LfmX/)

var rootMapping = {
    'items': {
        create: function(options) {
            return ko.mapping.fromJS(options.data, subitemMapping);
        },
        key: function(data) {
            return ko.utils.unwrapObservable(data.id);
        }
    }
};

var subitemMapping = {
    'subdata': {
        key: function(data) {
            return ko.utils.unwrapObservable(data.subId);
        }
    }
};

Upvotes: 1

Related Questions