2012-04-13 1 views
2

У меня есть шаблон KnockoutJS, который выглядит примерно так:KnockoutJS обновление Mapping не работает корректно с <- ко-Еогеасп: -> стиль связывания

<div data-bind="template: {name: 'testTemplate', data: people}"></div> 

<script id="testTemplate" type="text/html"> 
    <!--ko foreach: $data-->   
    <div class="items" data-bind="text: full() + ' updated at: ' + Date()"></div> 
    <!--/ko--> 
</script> 

После запуска энного количества тестов, я понял, что создание такого шаблона ошибочно, так как KnockoutJS будет обновлять шаблон каждый раз, даже если данные не изменяются.

Я проиллюстрировал это с помощью этих двух скрипок:

Как вы можете видеть, если вы фунт начальной загрузки , или загружать обновленные кнопки данных в привязке foreach, пользовательский интерфейс никогда не перерисовывается, если данные фактически не изменяются. К сожалению, если вы сделаете то же самое в привязке стиля данных, он будет повторно отображаться каждый раз.

Я действительно не могу понять, в чем разница. У меня создалось впечатление, что привязка данных работает так же, как и foreach, но позволяет больше контролировать объект внутри шаблона.

Единственная причина, по которой я его использую, состоит в том, что у меня есть набор вложенных шаблонов, и мне нужно приблизиться к реальному объекту. Я должен уметь рефакторировать и избегать этого подхода, но мне все еще остается интересно, почему это проблема.

Должно ли <!--ko foreach:--> соблюдать тот же шаблон, который используется для привязки шаблона foreach?

ответ

3

Проблема в том, что привязка к шаблону создает подписку на ваш наблюдаемый массив people, поскольку он передается как data. Когда обновляется массив people (элементы, нажатые/удаленные и т. Д.), Это приведет к привязке шаблона к повторной обработке шаблона. В вашем случае это повторно отображает весь контент, поэтому foreach внутри шаблона никогда не получит шанс быть эффективным.

Простой способ избежать этого - убедиться, что привязка шаблона не разворачивает ваш наблюдаемый массив people. Вы можете передать данные, как { myArray: people }, а затем сделать свой foreach по телефону myArray.

Вот пример: http://jsfiddle.net/rniemeyer/bVPwM/4/

+0

Вы понимаете, сейчас я просто пытаюсь придумать вопрос, который вы не можете ответить :). Ха-ха ... отличное решение! – farina

+0

Я заметил, что то же самое происходит с farina

+0

'if' является оболочкой привязки шаблона, поэтому да, поведение будет аналогичным. –