Canjs - Когда использовать какой тег усов при переборе списков?
Кажется, в Can.js есть несколько разных способов сделать то же самое, и это здорово! Но некоторые способы работают немного иначе, чем другие, и могут влиять на то, как DOM отображается и обновляется. Буду признателен, если кто-то сможет прояснить нюанс.
Я думаю, что сценарий, в котором этот выбор становится интересным, - это когда вам нужен текст по умолчанию или заполнитель для пустого списка.
{{#if list}} и {{#if list.length}}
Это не одно и то же. И пустой массив, и can.List будут отображать для {{#if list}}
,
{{# каждый список}}
Таким образом, используя то, что мы узнали с #if
...
{{#if list.length}}
<ul>
{{#each list}}
<li>...<li>
{{/each}}
</ul>
{{else}}
<i>The list is empty.</i>
{{/if}}
{{#список}}
Я думаю, что это должно быть лучшим из обоих миров. Сегодня мне пришло в голову, что, поскольку это блок помощник, он поддерживает {{else}}
,
{{#list}}
rendered for each item in list
{{else}}
rendered once if list is empty
{{/list}}
Дело в том, что это не может произвести HTML, который мы сделали с #each
,
- Оберните все это в
<ul>
тег, он отображается независимо от того, пустой список или нет - Придерживайтесь
<ul>
тег в первом блоке (положительный блок "утвердительный"), и он отображается каждый раз
Таким образом, реализация, кажется, зависит от разметки. Справедливо.
Вот руб.
Предположительно, #each
а также #list
обновить DOM по-другому. Из документов для #each
...
Если значение ключа - can.List, результирующий HTML обновляется при изменении списка. Когда происходит изменение в списке, происходит только минимальное количество изменений элемента DOM.
Так что добавьте один элемент в список, только этот элемент отображается, удалите элемент, только этот элемент будет удален. Поведение #list
не задокументировано, но у меня сложилось впечатление, что он может перерисовать весь блок.
Вопросы
Какой лучше? Помимо краткости, я не уверен #list
имеет какие-то преимущества, так почему авторы предполагают, что это предпочтительнее?
1 ответ
Предполагая, что список является экземпляром can.List:
{{#if list}}
проверим истинность значения списка. Это похоже на проверку истинного значения любого объекта JS и приведет к true, независимо от содержимого списка или длины.
{{#if list.length}}
проверит истинное значение атрибута длины. Если у вас есть пустой список, длина будет равна 0, поэтому #if приведет к значению false, и содержимое не будет отображаться. Если есть длина>= 1, это приведет к значению true и будет отображено содержимое #if.
#each
а также #list
оба перебирают экземпляр can.List, однако мы устанавливаем привязки по-разному.
#each
будет устанавливать привязки для каждого отдельного элемента, проходящего через #list
не буду. Это имеет значение в двух сценариях:
1) У вас большой список с минимальными обновлениями, запланированными после первоначального рендеринга. В этом случае, #list
может быть более выгодным, так как будет более быстрый начальный рендеринг. Однако, если какая-либо часть списка изменится, весь #list
Площадь будет переработана.
2) У вас большой список со многими обновлениями, запланированными после первоначального рендеринга. Сетка со многими столбцами редактируемых полей, например. В этом случае вы много хотите использовать #each
даже при том, что он будет медленнее при начальном рендеринге (мы устанавливаем больше привязок), у вас будут более быстрые обновления, так как теперь есть много разделов.
Быстрое замечание о вашем случае, если список содержит содержимое..., иначе пустая область списка:
{{#each items}} Перебирая элементы списка! {{/}} Каждая
{{^if items.length}} Показать, если нет товаров! {{/если}}
Выше следует учитывать этот сценарий. Если есть дополнительная логика, я бы подумал написать собственный помощник (в зависимости от того, как выглядит логика).