Шаблон KnockoutJS ‘beforeRemove’ вызывается три раза вместо 1

#javascript #knockout.js

#javascript #knockout.js

Вопрос:

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

        <div id="wrapper" data-bind="template: {
                                                name:'theTemplate', 
                                                foreach: cars(),  

                                                beforeRemove: function(elem) { 
                                                    console.log(elem);                                     
                                                    console.log('try removing..');
                                                    try {
                                                        jQuery(elem).hide().remove();
                                                    } catch (e) {
                                                        console.log(e);
                                                    }
                                                },

                                                afterAdd: function(elem) { 
                                                    console.log('try adding..');
                                                    try {
                                                        jQuery(elem).hide().fadeIn();
                                                    } catch (e) {
                                                        console.log(e);
                                                    }
                                                }
                                            }"></div>
  

Когда я удаляю объект из cars() observableArray, я хочу скрыть () и удалить () элемент, который удаляется. За исключением случаев удаления элемента, функция beforeRemove вызывается три раза с тремя разными элементами в качестве параметра.

Три элемента:

  1. Comment { data=" Block 1 ", length=9, nodeName="#comment", meer...} попробуйте удалить..

  2. <TextNode textContent=" "> попробуйте удалить..

  3. <div class="block"> попробуйте удалить..

afterAdd ведет себя точно так же.. Это ошибка или я неправильно понимаю функцию?

Спасибо за ваше время!

Ответ №1:

Я считаю, что это ожидаемое поведение, если ваш шаблон содержит эти элементы.

Если вы хотите скрыть / показать только определенные элементы — скажем, элементы <div> — вам нужно использовать селектор jQuery для фильтрации элементов:

 afterAdd: function(elem) { 
    console.log('try adding..');
    try {
        jQuery(elem).filter("div").hide().fadeIn();
    } catch (e) {
        console.log(e);
    }
}
  

Связанный: я не рекомендую помещать большие функции javascript прямо в ваш HTML. Это загромождает HTML и смешивает представление и логику представления. Вместо этого я бы сделал что-то вроде этого:

 <div id="wrapper" data-bind="template: {
    name:'theTemplate', 
    foreach: cars,
    beforeRemove: onRemovingCar,
    afterAdd: onAddedCar
}"></div>

<script type="text/javascript">

  var viewModel = {
     onRemovingCar: function(element) { 
          console.log(element);                                     
          console.log('try removing..');
          try {
              jQuery(element).hide().remove();
          } catch (e) {
              console.log(e);
          }
      },
      onAddedCar: function(element) { 
          console.log('try adding..');
          try {
              jQuery(element).hide().fadeIn();
          } catch (e) {
              console.log(e);
          }
      }
  };

</script>
  

Комментарии:

1. Спасибо, я бы исправил другой (аналогичный) способ, но ваш anwser — хороший вариант! Кроме того, часть «де-javascript» шаблона html является хорошим моментом!