2012-06-16 54 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);和代碼的作品。謝謝 –