2

私はノックアウトとマッピングプラグインを試していますが、なぜこれが機能しないのか疑問に思っています。マッピング拡張機能を使用してロードしたいビューモデルがあります

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

マッピングへの最初の呼び出しは成功しますが、2番目の呼び出しはstackoverflowで失敗します:( Chromeでは「UncaughtRangeError:Maximum call stacksizeexceeded」)

マッピングにオプションを渡さないようにコードを変更すると、例外はスローされません。

ToDoコンストラクターをこれに単純化してみました

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

    return todoItem;
};

しかし、それでも同じエラーが発生します。

これができないようですが、なぜだろうと思っていました。

4

1 に答える 1

3

問題はこのビットにあります:

TodoItem.options = {
    create: TodoItem 
};

TodoItemをプロパティ「options」で拡張します。これも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);
    }
};
于 2012-06-16T08:57:43.607 に答える