问题
I'm having endless recursion on IE by my knockout.js mapping. Can someone more familiar with KO to spot what am I doing wrong?
I have following knockout.js mapping:
var mapping = {
create: function(options) {
return new MyViewModel(options.data);
},
'ChildItems': {
create: function(options) {
return new ChildVM(options.data);
}
}
}
When I render the page approx. 1 time out of 5 IE ends up with following infinite recursion stack(causing "SCRIPT28: Out of stack space"). IE's callstack:
fromJS
MyViewModel
create
Anonymous Function
withProxyDependentObservable
createCallback
updateViewModel
fromJS
MyViewModel
create
Anonymous Function
withProxyDependentObservable
createCallback
updateViewModel
...
My view model constructor:
function MyViewModel(data) {
var self = this;
this.$type = 'MyViewModel';
[some observables]
...
ko.mapping.fromJS(data, mapping, this);
}
Initializing of view model is done by calling json endpoint:
$.ajax({
url: 'http://my.end/point',
type: 'POST',
data: JSON.stringify(payload),
contentType: 'application/json; charset=utf-8',
success: function(data) {
window.vm = ko.mapping.fromJS(data, mapping);
ko.applyBindings(window.vm)
}
});
回答1:
You should divide your mapping object to 2 objects. Use first for mapping view model and second for children.
var mapping = {
create: function(options) {
return new MyViewModel(options.data);
}
}
var childrenMapping = {
'ChildItems': {
create: function(options) {
return new ChildVM(options.data);
}
}
}
Your ajax request remain the same. Update MyViewModel function to use childrenMapping :
function MyViewModel(data) {
var self = this;
this.$type = 'MyViewModel';
[some observables]
...
ko.mapping.fromJS(data, childrenMapping, this);
}
The root cause of the issue is recursive calling of mapping. When you call ko.mapping.fromJS(data, mapping);
knockout calls create rule where creates MyViewModel object. In MyViewModel's constructor you call ko.mapping.fromJS
due to the using of the same mapping options knockout calls the same create rule that creates MyViewModel object where ko.mapping.fromJS
is called with the same options.
来源:https://stackoverflow.com/questions/12006433/knockout-js-mapping-causing-infinite-recursion-on-ie9