2011-12-30 3 views
0

Я пытаюсь получить голову вокруг наблюдаемых в нокауте js! Однако я столкнулся с проблемой реализации функции remove в наблюдаемом массиве.нокаут js remove не работает

Моего JS выглядит следующим образом:

$(function() { 
    var data = [{ name: "name1" }, { name: "name2" }, { name: "name3"}]; 
    var viewModel = { 
     namesList: ko.observableArray(data), 
     nameToAdd: ko.observable("name4"), 
     myCustomAddItem: function() { 
      this.namesList.push({ name: this.nameToAdd() }); 
     }, 
     myCustomRemove: function() { 
      console.log("before + " + this.nameToAdd()); 
      this.namesList.remove(this.nameToAdd()); 
      console.log("after + " + this.nameToAdd()); 
     } 
    }; 
    ko.applyBindings(viewModel); 
}); 

и мой HTML является:

Name To add/remove <input type="text" data-bind="value: nameToAdd, valueUpdate: 'afterkeydown'"/> 
<ul data-bind="template: {name: 'listTemp1', foreach :namesList}"> 

</ul> 
<p> 
    <button data-bind="click: myCustomAddItem">Add Item</button> 
    <button data-bind="click: myCustomRemove">Remove Item</button> 

    <script id="listTemp1" type="text/html"> 
     <li data-bind="text:name"> </li> 
    </script> 
</p> 

моего myCustomAddItem работает отлично, но не myCustomRemove. Я также поставил console.log до и после this.namesList.remove(this.nameToAdd());, чтобы увидеть, что там что-то не так, но я не вижу никакой ошибки там. Когда я нажимаю кнопку «Удалить элемент», консоль firebug показывает журналы, но элемент не удаляется из списка.

Любая помощь оценили

ответ

6

Параметром remove должна быть функция, которая возвращает истину или ложь о том, чтобы удалить что-нибудь.

Он работает совершенно аналогично функции filter.

В вашем случае, что-то, как это должно работать:

myCustomRemove: function() { 
    console.log("before + " + this.nameToAdd()); 

    var nameToAdd = this.nameToAdd(); 
    this.namesList.remove(function(item) { 
     //'item' will be one of the items in the array, 
     //thus we compare the name property of it to the value we want to remove 
     return item.name == nameToAdd; 
    }); 

    console.log("after + " + this.nameToAdd()); 
} 
3

[это должно быть комментарий Яни ответ, но я не могу до сих пор комментировать другие отправлять, извините] Только небольшое уточнение: технически вы можете вызвать remove(), передав элемент для удаления, см. раздел «remove and removeAll» на http://knockoutjs.com/documentation/observableArrays.html.

Проблема с вашим кодом заключается в том, что элементы в массиве данных являются объектами (содержащими свойство под названием «имя»), и вы просите удалить из массива строку «name4» (или что-то вроде «nameToAdd») содержит).

Вы можете быть соблазн создать новый объект, чтобы пройти, чтобы удалить, например:

// old code 
//this.namesList.remove(this.nameToAdd()); 
this.namesList.remove({ name: this.nameToAdd() }); 

, но это по-прежнему не удается, потому что путь Javascript работает объект равенства (см, например: How to determine equality for two JavaScript objects?).

Итак, в конце концов вам нужно использовать функцию в любом случае.

В этом простом примере вы также можете преобразовать массив namesList в простой массив строк и связать «$ data» в шаблоне. см. http://jsfiddle.net/saurus/usKwA/. В более сложном сценарии, возможно, вы не можете избежать использования объектов.

+0

Спасибо за подробный комментарий. Это действительно помогает понять, что происходит сейчас :) – CjCoax

0

[наблюдаемыйArray] .remove (функция (item) {return item. [Whatever] == [somevalue];});

Смежные вопросы