Knockout mapping - 使用键唯一地识别嵌套对象

时间:2012-08-17 17:01:08

标签: javascript knockout.js knockout-mapping-plugin

The Knockout mapping plugin documentation有一个标题为“使用”键“”唯一识别对象的部分。这描述了如何更新对象的一部分,然后只更新显示的那一部分,而不是完全替换部分修改对象的所有属性的显示。这一切都在他们简单的例子中得到了很好的体现,我在这里稍作修改,使我的问题更清楚。我的修改是:

  1. 延迟2秒后,用更正的名称替换对象。

  2. 突出显示不变的部分,以便在更新发生时可以看到它实际上没有被替换。

  3. 1。简单对象jsFiddle

    <h1 data-bind="text: name"></h1>
    <ul data-bind="foreach: children">
        <li><span class="id" data-bind="text: id"></span> <span data-bind="text: name"></span></li>
    </ul>
    
    <script>
    var data = {
        name: 'Scot',
        children: [
            {id : 1, name : 'Alicw'}
        ]
    };
    var mapping = {
        children: {
            key: function(data) {
                console.log(data);
                return ko.utils.unwrapObservable(data.id);
            }
        }
    };
    var viewModel = ko.mapping.fromJS(data, mapping);
    ko.applyBindings(viewModel);
    
    var range = document.createRange();
    range.selectNode(document.getElementsByClassName("id")[0]);
    window.getSelection().addRange(range);
    
    setTimeout(function () {
        var data = {
            name: 'Scott',
            children: [
                {id : 1, name : 'Alice'}
            ]
        };
        ko.mapping.fromJS(data, viewModel);
    }, 2000);
    </script>
    

    但我不清楚的是如何为更复杂的嵌套数据结构实现相同的行为。在下面的示例中,我使用上面的代码并将数据包装在列表中。我希望这与上面的行为相同,但事实并非如此。由于一个属性的变化,整个显示重做。您可以看到这一点,因为与上面的示例不同,数据更新后突出显示会丢失。

    2。更复杂的嵌套对象jsFiddle

    <!-- ko foreach: parents -->
        <h1 data-bind="text: name"></h1>
        <ul data-bind="foreach: children">
            <li><span class="id" data-bind="text: id"></span> <span data-bind="text: name"></span></li>
        </ul>
    <!-- /ko -->
    
    <script>
    var data = {
        parents: [
            {
                name: 'Scot',
                children: [
                    {id : 1, name : 'Alicw'}
                ]
            }
        ]
    };
    var mapping = {
        children: {
            key: function(data) {
                console.log(data);
                return ko.utils.unwrapObservable(data.id);
            }
        }
    };
    var viewModel = ko.mapping.fromJS(data, mapping);
    ko.applyBindings(viewModel);
    
    var range = document.createRange();
    range.selectNode(document.getElementsByClassName("id")[0]);
    window.getSelection().addRange(range);
    
    setTimeout(function () {
        var data = {
            parents: [
                {
                    name: 'Scott',
                    children: [
                        {id : 1, name : 'Alice'}
                    ]
                }
            ]
        };
        ko.mapping.fromJS(data, viewModel);
    }, 2000);
    </script>
    

    所以基本上我要问的是,如果给出更多嵌套的数据结构,我怎么能让第二个例子像第一个一样工作呢?你可以假设id对每个孩子都是唯一的(所以如果我在Scott之外添加了另一个父母,他的孩子会以id = 2等开始)。

1 个答案:

答案 0 :(得分:2)

有趣的观察和好的写作。如果您在父项和子项上定义键,它似乎有效。试试这个小提琴:

http://jsfiddle.net/8QJe7/6/

它为父项和子项定义了可实例化的视图模型函数,其中父构造函数执行其子映射。