KnockoutJS无法从observableArray中删除对象

时间:2014-05-29 18:14:16

标签: javascript arrays knockout.js

我有以下代码:

var testVM = {
  things: ko.observableArray([
    { id: 1, name: "Apple" },
    { id: 2, name: "Banana" },
    { id: 3, name: "Orange" },
    { id: 4, name: "Pineapple" },
    { id: 5, name: "Pear" }
    ]),

  deleteThing: function (data) {
    var things = testVM.things;
    var index = things.indexOf(data);

    // Debug...
    console.log('data', data);
    console.log('index', index);

    if (index > -1) {
        things.splice(index, 1)
    }
  },

  deleteApple: function () {
    this.deleteThing({ id: 1, name: "Apple" });
  }

};

ko.applyBindings(testVM);

使用HTML:

<ul data-bind="foreach: things">
  <li>
    <a data-bind="click: $root.deleteThing">X</a>&nbsp;|&nbsp;
    <span data-bind="text: name"></span>
  </li>
</ul>
<a data-bind="click: deleteApple">Delete Apple</a>

我在Fiddle创建的。我遇到的问题是,当从data-bind="click: deleteThing" foreach调用deleteThing时,deleteApple函数可以正常工作,但是如果(observableArray方法的话) )我尝试手动删除从未找到索引的内容,然后从console.log中删除该项目。

我很难过,因为在这两个实例中,{{1}}都显示相同的数据。

2 个答案:

答案 0 :(得分:2)

您遇到的问题与对象引用有关。在deleteApple函数中,您传递的是与原始对象引用不匹配的新对象。

remove API确实接受了一个函数,该函数传递了您可以返回truthy / falsy的项目,无论您是否要删除该项目。

在observableArray上使用remove的示例:

deleteApple: function () {
    this.things.remove(function(item) {
       return item.id === 1 && item.name === "Apple";   
    });
}

更新了小提琴:http://jsfiddle.net/rniemeyer/5HPxZ/

答案 1 :(得分:2)

原因是您尝试删除不在数组中的对象:

this.deleteThing({ id: 1, name: "Apple" });

虽然属性的值相同,但对象不同。对象是引用,您需要正确的引用,即您需要查找项的索引,然后在该索引处删除:

for(var i = 0;i<testVM.things.length;i++){
    if(testVM.things[i].id === 1){
        things.splice(index, 1);
    }
}

要测试我对引用的含义,请尝试执行以下代码:

var x = { id: 1, name: "Apple" };
var y = { id: 1, name: "Apple" };
alert(x === y): // Alerts false