Knockout.js 敲除映射插件中的数组错误还是我的代码?

Knockout.js 敲除映射插件中的数组错误还是我的代码?,knockout.js,knockout-mapping-plugin,knockout-2.0,Knockout.js,Knockout Mapping Plugin,Knockout 2.0,我最近注意到,当使用KO映射插件更新页面上的数据时,有一些事情值得关注。我认为第一个已在2.1.1中修复,第二个仍存在,如下所示: 我有一个简单的模型。问题在于它包含的地址数组。当我使用映射插件时,它似乎跟踪数组中的2个元素,而实际上只有一个元素。我不确定这是我的代码还是映射插件的问题。请考虑以下简单的例子: //Retrieved thru AJAX var serverData = { name: "Bob", Addresses: [{ AddressLine: "", City: "",

我最近注意到,当使用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]);
       }
    }

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

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

这将产生一个包含所有需要注意的元素的列表-当前元素具有键“0”,新元素具有键“1”,因此“mappedProperties”中存在奇怪的条目。我认为这可以被认为是一个bug,但它确实是一个非常棘手的bug。而且这不是真正的内存泄漏,因为重影条目的数量总是
numPreviousEntries


这里有一个fiddle演示了使用唯一键(如果没有多行,可以是任何键,因此我使用了state id)确实解决了这个问题:

您能用这个fiddle复制您的问题吗?我从来不会看到超过一个地址。可以我明白你的意思。虽然视图模型中没有显示第二个地址,但我确实在mappedProperties中看到了这两个条目。在2.1.0版本中,这段代码还将继续增加include[],并在每次更新中添加额外的“\u destroy”条目。现在似乎已经解决了,但我对内存泄漏感到紧张,因为在我的场景中更新的频率很高。