2013-04-30 18 views
8

Mam model widoku, który zawiera kolekcję obiektów, "Pliki".Knockout - Usuwanie elementu z ViewModel nie usuwa z DOM

Oczywiście jest to związane z DOM.

Po usunięciu elementu z kolekcji "Pliki" oczekiwałbym, że DOM zostanie zaktualizowany, aby to odzwierciedlić, ale nie zostanie zaktualizowany.

To jest JS, którego używam do usuwania elementu z kolekcji "Pliki".

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); 

Gdybym wydrukować długość kolekcji do konsoli po wywołaniu Usuń (ID), widzę, że przedmiot został zostały usunięte.

Dlaczego więc DOM nie aktualizuje się?

Jeśli zadzwonię ko.applyBindings (... to robi aktualizację, ale mój zrozumienia jest to, że nie powinno się nazywać to za każdym razem aktualizacje widoku modelu.

Więc co może być ? robi źle

również próbowałem go z plikami jako observableArray i standardowej tablicy, bez jakiejkolwiek różnicy

UPDATE:. oto definicja modelu widoku (no ... odpowiednia część, tak))

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); 

    ... 
} 

Ja również próbowałem go z

self.Files = []; 

a następnie zmieniając każde wystąpienie Files(), aby tylko pliki. Bez różnicy.

+1

Jak 'Files' zdefiniowana? Powinien to być "obserwowalna tablica", w przeciwnym razie może działać ... Powiedziałeś, że próbowałeś z 'observableArray' czy możesz opublikować tę wersję swojej funkcji' Delete'? – nemesv

Odpowiedz

8

Trzeba mieć obserwowalnym tablicy:

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

ale trzeba zadzwonić splice bezpośrednio na obserwowalnym tablicy z 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); 

inaczej usunąć element tworzą podstawową tablicę bez KO wiedząc o usunięciu, więc nie może zaktualizować DOM. Zobacz także dokumentację Manipulating an observableArray.

Przy okazji observableArray ma remove funkcję, która może znacznie uprościć kod:

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

Jezu, takie proste, a jednak prawdopodobnie spędziłem kilka godzin próbując to zrozumieć. Wielkie dzięki, @ saturesv. – awj

+0

Potrzebna jest jedna mała modyfikacja. Sugestia file.remove jest taka, że ​​item.ID() powinien być po prostu item.ID (bez nawiasów). Dzięki jeszcze raz. – awj

+0

Masz '.ID()' w twoim próbku ... Właśnie skopiowałem i założyłem, że twoja własność 'ID' jest' ko.observable' – nemesv

Powiązane problemy