Knockout - Deleting item from ViewModel doesn't remove from DOM

knockout.js

Solution

You need to have the observable array:

self.Files = ko.observableArray([]);

but you need to call `splice` directly on the observable array with `this.Files.splice`:

this.Delete = function(id) {
    // find which index the specified ID exists at
    for (var f = 0; f < this.Files().length; f++) {
        if (this.Files()[f].ID() == id) {
            this.Files.splice(f, 1);
        }
    }
}.bind(this);

otherwise you remove the item form the underlying array without KO knowing about the removal so it cannot update the DOM. See also the documenation Manipulating an observableArray section.

By the way the observableArray has a `remove` function which could greatly simplify your code:

this.Delete = function(id) {
    this.Files.remove(function(item) { return item.ID() == id; } );        
}.bind(this);

Problem

I have a view model which contains a collection of objects, 'Files'. Obviously this is bound to the DOM. When I remove an item from the 'Files' collection I would expect the DOM to be updated to reflect this, but it doesn't update. This is the JS that I use for removing an item from the 'Files' collection. ``` this.Delete = function(id) { for (var f = 0; f < this.Files.length; f++) { if (this.Files[f].ID() == id) { this.Files.splice(f, 1); } } }.bind(this); ``` If I print the length of the collection to the console after calling Delete(id), I can see that an item has been removed. So why does the DOM not update? If I call ko.applyBindings(... then it does update, but my understanding is that I shouldn't have to call this every time the view model updates. So what might I be doing wrong? Also, I've tried it with Files as an observableArray and a standard array, without any difference. UPDATE: here's the definition of the view model (well... the relevant part, anyway) ``` function Files(files) { var self = this; self.Files = ko.observableArray([]); this.Delete = function(id) { // find which index the specified ID exists at for (var f = 0; f < this.Files().length; f++) { if (this.Files()[f].ID() == id) { this.Files().splice(f, 1); } } }.bind(this); ... } ``` I've also tried it with ``` self.Files = []; ``` and then changing every instance of Files() to just Files. No difference.

Original source