knockout.js - Knockout 映射插件或我的代码中存在数组错误?

标签 knockout.js knockout-mapping-plugin knockout-2.0

我最近在使用 KO 映射插件更新页面上的数据时注意到一些有关的事情。我相信第一个现已在 2.1.1 中修复,第二个如下所示仍然存在:

我有一个简单的模型。问题在于它包含的地址数组。看来当我使用映射插件时,它会跟踪数组中的 2 个元素,而实际上只有一个元素。我不确定这是否是我的代码或映射插件的问题。请考虑以下简单示例:

//Retrieved thru AJAX
var serverData = { name: "Bob", Addresses: [{ AddressLine: "", City: "", PostalCode: "", StateID: 10}] };  

    load(serverData);  
    //Seems OK at this point
    //this.vm.__ko_mapping__.mappedProperties shows properties for Addresses[0] & name which makes sense


    //Now some time goes by and we want to update the bound VM w/ new data from the server
    load(serverData);  

    //Problem!
    //this.vm.__ko_mapping__.mappedProperties shows properties for Addresses[0] & Addresses[1]
    //But there is no Addresses[1]!!

    //Lets simulate an update of data (1 more time)
    load(serverData);
    //Interestingly it doesn't get any worse, still just Addresses[0] & Addresses[1]

    function load(d)
    {  
       if (this.vm) //Refresh existing VM
       {
          ko.mapping.fromJS(serverData, vm);
       }
       else    //On 1st Load have mapping create the VM and bind it
       {
          this.vm = ko.mapping.fromJS(serverData);   //Mapping creates object from server data
          ko.applyBindings(this.vm, $("body")[0]);
       }
    }

最佳答案

映射插件允许定义一个回调,返回数组中元素的键。 (请参阅 http://knockoutjs.com/documentation/plugins-mapping.html 处的“使用键唯一标识对象”)。这用于确定对象是新的还是旧的。存在三种可能的状态:一个新对象被添加到数组中,一个已经存在的元素保留在数组中(但被更新)或者一个现有元素被从数组中删除,因为它不再存在于新数据集中。 (这些状态实际上是由实用函数 ko.utils.compareArrays 确定的)

这里正确的状态是“保留”,但是由于您没有为数组中的地址提供唯一的键,因此映射插件不知道这些条目实际上是相同的 - 因此状态“删除”得到分配给当前对象并将状态“添加”到新对象。

这会产生一个包含所有需要注意的元素的列表 - 当前的元素具有键“0”,新的元素具有键“1”,因此“mappedProperties”中出现奇怪的条目。我认为这可以被认为是一个错误,但它是一个非常棘手的错误。这并不是真正的内存泄漏,因为幽灵条目的数量始终是 numPreviousEntries

这里有一个 fiddle ,证明使用唯一键(如果你不超过一行,可以是任何东西,所以我使用了状态 ID)确实解决了这个问题:http://jsfiddle.net/xTHFg/4/

关于knockout.js - Knockout 映射插件或我的代码中存在数组错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10179389/

相关文章:

javascript - 使用 ko.mapping.fromJS 进行异步 ajax 调用后更新可观察的 knockout

knockout.js - 使用 "with"设置上下文时 knockout $parent 的疑问

javascript - knockoutjs 映射插件从对象中删除功能

javascript - toJSON View 模型覆盖在 Knockout 取消映射后未反射(reflect)出来

jQuery Knockout - 动态添加和删除 html 属性

jquery - 我什么时候应该将事件绑定(bind)到 Knockout 绑定(bind)生成的元素?

javascript - knockout JS : Checking if items in nested sortable were reordered

knockout.js - 如果已在上一行或下一行中选择项目,则如何从选择下拉列表中删除项目

javascript - 自动关闭 knockout 评论中的 <a> 标签

Javascript:仅在其自己的函数内直接修改数组