Reputation: 5210
I have the following code:
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);
With the HTML:
<ul data-bind="foreach: things">
<li>
<a data-bind="click: $root.deleteThing">X</a> |
<span data-bind="text: name"></span>
</li>
</ul>
<a data-bind="click: deleteApple">Delete Apple</a>
Which I've created in a Fiddle. The issue I'm having is that when invoked from a data-bind="click: deleteThing"
inside a foreach
the deleteThing
function works fine, however if (in the case of the deleteApple
method) I attempt to manually delete something it never finds the index and subsequently doesn't delete the item from the observableArray
.
I'm stumped because in both instances the console.log
shows the same data.
Upvotes: 1
Views: 61
Reputation: 28737
The reason is that you try to delete an object that is not in the array:
this.deleteThing({ id: 1, name: "Apple" });
Although the values of the properties is the same, the objects are different. Objects are references and you need the correct reference, ie you need the find the index of the item and then delete at that index:
for(var i = 0;i<testVM.things.length;i++){
if(testVM.things[i].id === 1){
things.splice(index, 1);
}
}
To test what I mean about references, try and execute the following code:
var x = { id: 1, name: "Apple" };
var y = { id: 1, name: "Apple" };
alert(x === y): // Alerts false
Upvotes: 2
Reputation: 114792
The issue that you are having is related to object references. In your deleteApple
function you are passing a new object that does not match the original object reference.
The remove
API does accept a function that passes the item in where you can return truthy/falsy whether you want to remove the item.
Example of using remove
on an observableArray:
deleteApple: function () {
this.things.remove(function(item) {
return item.id === 1 && item.name === "Apple";
});
}
Updated fiddle: http://jsfiddle.net/rniemeyer/5HPxZ/
Upvotes: 2