我正在尝试淘汰赛和映射插件,并想知道为什么这不起作用。我有一个要使用映射扩展加载的视图模型
function todoListViewModel(data) {
ko.mapping.fromJSON(data, { todos: TodoItem.options }, self);
ko.mapping.fromJSON(data, { todos: TodoItem.options }, self);
}
映射有一个如下所示的选项:
var TodoItem = function (options) {
var todoItem = ko.mapping.fromJS(options.data);
todoItem.remove = function () {
alert('remove');
};
return todoItem;
};
TodoItem.options = {
create: TodoItem
};
JSON 数据如下所示:
{
"id": "0",
"todo": "",
"todos": [
{
"todo": "Kevin",
"isDone": true
}
]
}
对映射的第一次调用成功,但第二次调用失败并出现堆栈溢出:
(Chrome 中的“未捕获范围错误:超出最大调用堆栈大小”)
如果我更改代码以便不向映射传递选项,则不会引发异常。
我还尝试将 ToDo 构造函数简化为此
var TodoItem = function (options) {
var todoItem = {};
return todoItem;
};
但我仍然遇到同样的错误。
看起来我不能这样做,但我想知道为什么?
问题出在这一点上:
TodoItem.options = {
create: TodoItem
};
您使用属性“options”扩展 TodoItem,该属性再次包含 TodoItem - 因此函数 TodoItem 有一个包含自身的属性。
TodoItem.options.create == TodoItem
TodoItem.options.create.options.create == TodoItem
TodoItem.options.create.options.create.options.create == TodoItem
...
因为它只是一个引用,所以这在 JavaScript 中没有问题。但是淘汰映射插件似乎对该选项对象执行一些复制操作(或具有相同效果的操作),即它尝试迭代其所有属性,因此最终陷入无限循环。
您可以通过使用匿名函数作为包装器轻松解决此问题:
TodoItem.options = {
create: function(options) {
return new TodoItem(options);
}
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)