淘汰赛映射造成计算器(knockout mapping causing stackoverflow)

2019-09-18 04:07发布

我与淘汰赛和映射插件试验和奇怪,为什么这是行不通的。 我有我想要使用映射扩展加载一个视图模型

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
        }
    ]
}

到映射所述第一呼叫成功,但第二呼叫失败,计算器:(“未捕获的RangeError:超过最大调用堆栈大小”在Chrome)

如果我改变了代码,使我没有通过选项映射,则没有抛出异常。

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

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

    return todoItem;
};

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

它看起来像我不能做到这一点,但我想知道为什么吗?

Answer 1:

问题是与该位:

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);
    }
};


文章来源: knockout mapping causing stackoverflow