文档中给出了Folliwing说明,我有以下视图模型:
var newContactViewModel = function () {
var self = this;
self.Name = ko.observable();
self.Address = ko.observable();
self.City = ko.observable();
self.State = ko.observable();
self.PostalCode = ko.observable();
self.Save = function () {
$.ajax({
type: "POST",
url: "/contact",
data: ko.toJS(self), //infinite loop here
success: state.OnSaved
});
};
};
Run Code Online (Sandbox Code Playgroud)
self.Save
调用该方法时,会发生无限循环.Chrome实际上将错误报告为:
未捕获RangeError:超出最大调用堆栈大小
如果我使用ko.mapping.toJS(self)
而不是ko.toJS(self)
,那么我会得到一个稍微更具启发性的错误,但没有真正的错误"消息":
如果我换掉ko.toJS(self)
类似的东西{ Name: self.Name(), Address: self.Address() /* etc */ }
,那么一切正常.似乎它正在尝试转换Save
方法并重新调用该方法.
在KnockoutJS中有一个错误,或者在我如何使用它时会出现问题.我更喜欢后者.思考?
Jef*_*ado 14
我发现了代码的问题. ko.toJS
保留对象中的函数,以便它能够很好地映射它.但是,jquery将调用数据对象上的所有函数来尝试获取值.这反过来导致无限循环.
您需要将Save
函数标记为不映射.不幸的是,该toJS
功能似乎无法做到这一点.它将保留对象的所有成员.幸运的是,映射插件允许您这样做.
要排除成员,请将ignore
选项设置为包含的数组,'Save'
并Save
在映射时忽略该成员.
var data = ko.mapping.toJS(self, {
ignore: ['Save']
});
Run Code Online (Sandbox Code Playgroud)
如果您没有使用映射插件,则始终可以选择Save
从JS对象中删除该函数.
self.Save = function () {
$.ajax({
type: "POST",
url: "/contact",
data: self.ToData(),
success: state.OnSaved
});
};
self.ToData = function () {
var data = ko.toJS(self);
delete data.Save; // remove functions
delete data.ToData;
return data;
};
Run Code Online (Sandbox Code Playgroud)
另一方面,我建议不要尝试使用视图模型实例作为调用的数据.我会明确地创建数据对象.当然它有可能很长,但这种方法很可能总能奏效.
self.ToData = function () {
return ko.toJS({
Name: self.Name,
Address: self.Address,
City: self.City,
State: self.State,
PostalCode: self.PostalCode
});
};
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1593 次 |
最近记录: |