2013-05-01 2 views
0

Я новичок в Knockout и все еще изучаю его.
У меня есть простая страница, чтобы пользователи могли добавлять и удалять элементы. Функция «удалить» (с именем «deleteItem») работает с кодами версии 1, но не с кодами версии 2. Пожалуйста, помогите мне узнать причину. Заранее спасибо.Функция «Удалить» работает и не работает с ko.observableArray()

Кстати, коды для версии 2 приходят от 7 Примечания вблизи дна по ссылке http://knockoutjs.com/documentation/foreach-binding.html#note_5_postprocessing_or_animating_the_generated_dom_elements

Код для версии 1 поступает из примера 2, в той же ссылке.

Подробная информация о моих кодов:

Разница между 2 версий:

В версии 1, свойство «myItems» представляет собой массив объектов, которые имеют свойство «имя».
В версии 2 свойство 'myItems' представляет собой массив элементов, который не имеет никакого свойства. Эти элементы массива являются буквальными строками.

Version 1 коды: функция "Удалить" (названный 'DeleteItem') работает

<div> 
    <ul data-bind="foreach: {data: myItems}"> 
     <li> 
      <span data-bind="text: $data.name"></span> <a href="#" data-bind="click : $parent.deleteItem" 

>Delete</a> 
     </li> 
    </ul> 
    <button data-bind="click: addItem">Add</button> 
</div 

<script type="text/javascript"> 
    $(function() { 
     function ViewModel() { 
      var self = this; 

      self.myItems = ko.observableArray([{ name: 'A' }, { name: 'B' }, { name: 'C' } ]); /*********/ 
      self.addItem = function() { self.myItems.push({ name: 'New item at ' + new Date() }); }   


      self.deleteItem = function() { 
       self.myItems.remove(this); 
      }; 
     } 

     ko.applyBindings(new ViewModel()); 

    }); 

</script> 

Version 2: функция "Удалить" (названный 'DeleteItem') не работает

<div> 
    <ul data-bind="foreach: myItems"> 
     <li> 
      <span data-bind="text: $data"></span> <a href="#" data-bind="click : $parent.deleteItem" 

>Delete</a> 
     </li> 
    </ul> 
    <button data-bind="click: addItem">Add</button> 
</div> 

<script type="text/javascript"> 
    $(function() { 
     function ViewModel() { 
      var self = this; 

      self.myItems = ko.observableArray(['A', 'B', 'C']); /*********/ 
      self.addItem = function() { self.myItems.push('item added at ' + new Date()); }; 

      self.deleteItem = function() { 
       self.myItems.remove(this); 
      }; 
     } 

     ko.applyBindings(new ViewModel()); 

    }); 

</script> 

ответ

2

Вы не должны ожидать, что this будет текущей моделью в обработчике click.

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

От documentation:

При вызове обработчика, Нокаут будет поставлять ток значение модели в качестве первого параметра.

Так что вам нужно переписать deleteItem к:

self.deleteItem = function (item) { 
    self.myItems.remove(item); 
}; 

Demo JSFiddle.

Примечание будет работать в обоих ваших образцов.

+0

nemesv, спасибо за ваше любезное объяснение и обновленное решение для кодов версии 2. Я дал вам голосование. –

+0

В скрипке, если вы добавите 5 новых элементов и выберите Удалить из второго добавленного элемента, он удалит все элементы с 2-го по 5-й добавленные элементы. – bhagyas

+0

@bhagyas yeah, потому что элементы являются строками, и если вы добавите их быстро, вы добавите одну и ту же строку снова и снова, чтобы удаление было путано. Если вы используете правильный объект вместо строк (или уникальных строк), он работает нормально: http://jsfiddle.net/8MR4w/2/ – nemesv

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