Reputation: 83848
Where an array is nested within an object the 'create' and 'update' callbacks of the Knockout.js mapping plugin are not called when one would expect. In particular, one would expect that calling the view_model.mappedCreate({})
would trigger the callbacks.
Here is an example, given a data structure and mapping like this:
var data = {
Test: {
Items: [
{ Name: "Red", Count: 0},
{ Name: "Green"}
]
},
NewItem: ""
},
counter = 0;
var vm = ko.mapping.fromJS(data, {
Test: {
Items: {
create: function(options) {
options.data.Count = ++counter;
console.log("Data:", options.data);
return ko.mapping.fromJS(options.data);
},
update: function(options) {
options.data.Count = ++counter;
console.log("Data:", options.data);
return ko.mapping.fromJS(options.data);
}
}
}
});
As you can see from this jsFiddle, the output of the above is:
{
"Test": {
"Items": [
{
"Name": "Red",
"Count": 0
},
{
"Name": "Green"
}
]
},
"NewItem": ""
}
Furthermore, the console.log
statements are never called.
One would expect the second element of Items
to be {"Name": "Green", "Count": 1 }
(and console.log statements to be executed).
When Items
is not nested, it works as expected - as you can see in this jsFiddle.
It is possible that I have overlooked something obvious, but in any case I would be grateful for insight and suggestions on how to work around this issue.
Upvotes: 1
Views: 1224
Reputation: 83848
The answer seems to have been to make the array name's mapping top-level, like this:
var vm = ko.mapping.fromJS(data, {
Items: {
create: function(options) {
options.data.Count = ++counter;
console.log("Create:", options.data);
return ko.mapping.fromJS(options.data);
},
update: function(options) {
options.data.Count = ++counter;
console.log("Update:", options.data);
return ko.mapping.fromJS(options.data);
}
}
});
As per this jsFiddle.
I am still encountering an issue in code I have elsewhere, but evidently the problem illustrated above was not it.
Upvotes: 1