挖空.js映射导致 IE9 上的无限递归

knockout.js mapping causing infinite recursion on IE9

本文关键字:无限 递归 IE9 js 映射 挖空      更新时间:2023-09-26

我通过我的淘汰.js映射在IE上进行了无休止的递归。更熟悉KO的人可以发现我做错了什么吗?

我有以下淘汰.js映射:


        var mapping = {
            create: function(options) {
                return new MyViewModel(options.data);
            },
            'ChildItems': {
                create: function(options) {
                    return new ChildVM(options.data);
                }
            }
        }

当我渲染页面大约 1 次中的 5 次时,IE 最终会出现以下无限递归堆栈(导致"SCRIPT28:堆栈空间不足")。IE的调用堆栈:


    fromJS
    MyViewModel
    create
    Anonymous Function
    withProxyDependentObservable
    createCallback
    updateViewModel
    fromJS
    MyViewModel
    create
    Anonymous Function
    withProxyDependentObservable
    createCallback
    updateViewModel
        ...

我的视图模型构造函数:

 function MyViewModel(data) {
            var self = this;
            this.$type = 'MyViewModel';
            [some observables]         
            ...
            ko.mapping.fromJS(data, mapping, this);
        }

视图模型的初始化是通过调用 json 端点来完成的:


            $.ajax({
                url: 'http://my.end/point',
                type: 'POST',
                data: JSON.stringify(payload),
                contentType: 'application/json; charset=utf-8',
                success: function(data) {
                    window.vm = ko.mapping.fromJS(data, mapping);
                    ko.applyBindings(window.vm)
                    }
            });

您应该将映射对象划分为 2 个对象。首先用于映射视图模型,第二次用于子项。

var mapping = {
            create: function(options) {
                return new MyViewModel(options.data);
            }
        }
var childrenMapping = {
                'ChildItems': {
                    create: function(options) {
                        return new ChildVM(options.data);
                    }
                }
}

您的 ajax 请求保持不变。更新 MyViewModel 函数以使用子项映射:

 function MyViewModel(data) {
            var self = this;
            this.$type = 'MyViewModel';
            [some observables]         
            ...
            ko.mapping.fromJS(data, childrenMapping, this);
        }

问题的根本原因是映射的递归调用。当您调用ko.mapping.fromJS(data, mapping);淘汰调用时,创建规则,其中创建 MyViewModel 对象。在 MyViewModel 的构造函数中,由于使用相同的映射选项,您调用ko.mapping.fromJS 挖空调用相同的创建规则,该规则创建 MyViewModel 对象,其中使用相同的选项调用ko.mapping.fromJS