Reputation: 365
When we apply the ViewModel for the first time everything works fine, but if we reapply the mapping after the computed fields has been created, they are deleted. This code obviously works if we don't change the key
http://jsbin.com/ojabaf/14/edit
var modelJs = {test:{
list: [{name: 'a', val: 5, list: [ {name:'b', val: 11}, {name: 'c', val: 13} ]}]}
};
var mapping = {
'list': {
key: function(data) { return ko.utils.unwrapObservable(data.name); }
},
'name': {
key: function(data) { return ko.utils.unwrapObservable(data.name); }
}
};
var model = ko.mapping.fromJS(modelJs, mapping);
ko.utils.arrayForEach(model.test.list(), function(item) {
item.comp = ko.computed({read: function() { return this.val() * 2; } , owner: item });
ko.utils.arrayForEach(item.list(), function(item2) {
item2.comp = ko.computed({read: function() { return this.val() * 3; } , owner: item2 });
});
});
ko.applyBindings(model);
$('button').click(function () {
var modelJs = {test: {val: 3, list: [{name: 'b', val: 7, list: [ {name:'s', val: 15}, {name: 'c', val: 17} , {name: 'd', val: 17}, {name: 'f', val: 17}]}]}};
ko.mapping.fromJS(modelJs, model);
});
Is there a way to recalculate those computed fields with the ko.mapping, and without refreshing the page?
I also tryed with templates... http://jsbin.com/ojabaf/15/edit
Upvotes: 1
Views: 1715
Reputation: 134841
Rather than looping over your arrays and adding the comp
computed observables to each item, set up your mapping so they are added when an item is created.
var mapping = {
'list': {
key: function (data) {
return ko.utils.unwrapObservable(data.name);
},
create: function (options) {
var mapped = ko.mapping.fromJS(options.data, {
'list': {
key: function (data) {
return ko.utils.unwrapObservable(data.name);
},
create: function (options) {
var mapped = ko.mapping.fromJS(options.data);
return ko.utils.extend(mapped, {
comp: ko.computed(function () {
return this.val() * 3;
}, mapped)
});
}
}
});
return ko.utils.extend(mapped, {
comp: ko.computed(function () {
return this.val() * 2;
}, mapped)
});
}
},
'name': {
key: function (data) {
return ko.utils.unwrapObservable(data.name);
}
}
};
var model = ko.mapping.fromJS(modelJs, mapping);
http://jsbin.com/asomiq/1/edit
Upvotes: 2