Директива repeat в FAST Element
обеспечивает высокопроизводительное рендеринг-повторение коллекций
данных в шаблонах. Директива связывает массив данных и разметку,
автоматически добавляя, обновляя и удаляя DOM-элементы при изменении
коллекции. Используется при работе со списками, таблицами, меню и любыми
структурами, где требуется динамическое повторение элементов.
repeat принимает три ключевых аргумента: источник
данных, опциональный ключ и шаблон элемента. Упрощённый синтаксис
выглядит так:
repeat(x => x.items, html`<div>${x => x}</div>`)
Источник данных может быть массивом или любым объектом, реализующим итерацию. Каждый элемент коллекции передаётся в шаблон как текущий контекст.
Ключ предназначен для выравнивания элементов данных с DOM-узлами при обновлениях. Это позволяет избежать полного пересоздания всего списка и повышает производительность при сортировках, фильтрациях и обновлениях отдельных элементов.
Пример с ключом:
repeat(
x => x.items,
x => x.id,
html`<item-element item=${x => x}></item-element>`
)
Ключ должен быть стабильным и уникальным для каждого элемента. При отсутствии ключа директива использует индекс массива, что может приводить к ненужным перерисовкам при изменении порядка элементов.
Обновление исходной коллекции вызывает диффинг-алгоритм FAST, который определяет изменения списка и применяет их к DOM. Операции вставки, удаления и перемещения выполняются максимально локально. Такая модель существенно снижает стоимость работы со списками в сравнение с полным повторным рендерингом.
Особенно важно при больших коллекциях: использование ключей и иммутабельных обновлений позволяет минимизировать объём операций.
repeat может использоваться в комбинации с другими
директивами и шаблонами, образуя сложные иерархии, например динамические
таблицы и деревья:
repeat(
x => x.rows,
x => x.id,
html`
<tr>
${repeat(
x => x.cells,
html`<td>${x => x.value}</td>`
)}
</tr>
`
)
Вложенные повторения корректно синхронизируются при изменениях данных как во вложенных коллекциях, так и в верхнем уровне.
В теле шаблона доступен локальный контекст элемента коллекции и полный контекст компонента. Это позволяет сочетать данные элемента, результаты вычислений и состояние компонента:
repeat(
x => x.items,
html`<div class="${(x, c) => c.parent.selected === x ? 'active' : ''}">
${x => x.label}
</div>`
)
Контекст компонента доступен через второй аргумент функции-байндинга и передается неизменным для всех элементов повторения.
repeat не ограничивается примитивами. Каждый элемент
списка может представлять собой пользовательский Web Component, который
получает данные через свойства или атрибуты:
repeat(
x => x.products,
x => x.id,
html`<product-card product=${x => x}></product-card>`
)
FAST обеспечивает корректную инициализацию и обновление свойств пользовательского элемента в процессе диффинга.
При работе с асинхронными коллекциями (например fetch-запросами) директива корректно реагирует на обновления после завершения загрузки. Часто используется совместно с реактивными свойствами компонента или сигналами состояния. В результате список появляется сразу после получения данных, а дальнейшие обновления не требуют дополнительных действий.
repeat не накладывает ограничений на предобработку
коллекции. Перед передачей массива в директиву могут применяться
сортировки, фильтры или маппинги:
repeat(
x => x.items.filter(i => i.visible).sort((a, b) => a.order - b.order),
x => x.id,
html`<list-item item=${x => x}></list-item>`
)
Важно обеспечивать стабильность ключей после таких операций, иначе потеряется оптимизация перемещений.
Ключевые рекомендации:
При соблюдении этих практик repeat обеспечивает плавный
рендеринг и масштабируемость интерфейсов.
По сравнению с примитивным рендерингом списков через перегенерацию
всего DOM-фрагмента при каждом изменении, директива repeat
дает:
Эти свойства делают repeat важным инструментом при
создании динамических интерфейсов на базе FAST Element.