2012-06-16 55 views
2

我正在尝试淘汰赛和映射插件,并想知道为什么这不起作用。我有我想要使用映射扩展淘汰赛映射导致stackoverflow

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中出现“Uncaught RangeError:Maximum call stack size exceeded”)

如果我更改代码,以便不将选项传递给映射,则不引发异常。

我也试着简化待办事项构造这个

var TodoItem = function (options) { 
    var todoItem = {}; 

    return todoItem; 
}; 

,但我仍然得到同样的错误。

看起来我不能这样做,但我想知道为什么?

回答

3

问题是与该位:

TodoItem.options = { 
    create: TodoItem 
}; 

你扩展的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); 
    } 
}; 
+1

不知道谁投下来,但它确实工作,我已经完全删除了TodoItem.options并更换KO .mapping.fromJSON(data,{todos:TodoItem.options},self);与ko.mapping.fromJSON(数据,{todos:{create:TodoItem}},self);和代码的作品。谢谢 –