Фреймворк Polymer предоставляет мощные средства для организации
динамического отображения повторяющихся данных с помощью специальных
шаблонов и привязок. Основным инструментом для работы с коллекциями
является элемент <dom-repeat>, который позволяет
создавать циклы по массивам данных и автоматически обновлять DOM при
изменении данных.
<dom-repeat><dom-repeat> используется для генерации
повторяющихся элементов на основе массива. Основные атрибуты:
items — массив данных, по которому выполняется
итерация.as — имя переменной для текущего элемента массива
внутри шаблона.index-as — имя переменной для текущего индекса
элемента.observe — массив свойств, за изменениями которых
необходимо следить для обновления шаблона.Пример базового использования:
<dom-module id="user-list">
<template>
<ul>
<dom-repeat items="[[users]]" as="user" index-as="i">
<template>
<li>[[i]]: [[user.name]] ([[user.age]] лет)</li>
</template>
</dom-repeat>
</ul>
</template>
<script>
class UserList extends Polymer.Element {
static get is() { return 'user-list'; }
static get properties() {
return {
users: {
type: Array,
value: () => [
{name: 'Иван', age: 30},
{name: 'Мария', age: 25},
{name: 'Пётр', age: 40}
]
}
};
}
}
customElements.define(UserList.is, UserList);
</script>
</dom-module>
В этом примере каждый объект массива users преобразуется
в элемент списка <li>. Изменения в массиве
автоматически отображаются в DOM.
<dom-repeat> поддерживает двустороннюю привязку,
что позволяет изменять данные в шаблоне и автоматически синхронизировать
их с моделью:
<dom-repeat items="[[users]]" as="user">
<template>
<input value="{{user.name::input}}">
</template>
</dom-repeat>
Атрибут {{user.name::input}} обеспечивает реакцию на
событие input, мгновенно обновляя массив
users.
<dom-repeat> предоставляет встроенные методы для
фильтрации и сортировки:
filter — функция фильтрации элементов.sort — функция сортировки элементов.Пример сортировки и фильтрации:
<dom-repeat items="[[users]]" as="user" filter="filterAdults" sort="sortByName">
<template>
<div>[[user.name]] ([[user.age]])</div>
</template>
</dom-repeat>
<script>
class UserList extends Polymer.Element {
static get is() { return 'user-list'; }
static get properties() {
return {
users: {
type: Array,
value: () => [
{name: 'Иван', age: 30},
{name: 'Мария', age: 25},
{name: 'Пётр', age: 40}
]
}
};
}
filterAdults(user) {
return user.age >= 18;
}
sortByName(a, b) {
return a.name.localeCompare(b.name);
}
}
customElements.define(UserList.is, UserList);
</script>
Элементы массива сначала фильтруются функцией
filterAdults, затем сортируются по алфавиту.
Polymer позволяет динамически изменять массивы с помощью методов
push, pop, splice,
shift, unshift, set и
автоматически обновлять <dom-repeat>:
this.push('users', {name: 'Алексей', age: 28});
this.splice('users', 1, 1, {name: 'Светлана', age: 32});
Каждое изменение корректно отражается в DOM без необходимости ручного рендеринга.
Внутри <dom-repeat> доступны переменные:
item или имя, указанное в as — текущий
элемент массива.index или имя, указанное в index-as —
индекс элемента.odd и even — булевы значения для нечётных
и чётных элементов, полезные для стилизации.<dom-repeat items="[[users]]" as="user" index-as="i">
<template>
<div class$="[[oddOrEven(i)]]">
[[user.name]]
</div>
</template>
</dom-repeat>
<script>
oddOrEven(index) {
return index % 2 === 0 ? 'even' : 'odd';
}
</script>
Поддерживаются вложенные <dom-repeat> для работы с
массивами массивов:
<dom-repeat items="[[users]]" as="user">
<template>
<h3>[[user.name]]</h3>
<ul>
<dom-repeat items="[[user.friends]]" as="friend">
<template>
<li>[[friend]]</li>
</template>
</dom-repeat>
</ul>
</template>
</dom-repeat>
Такой подход позволяет строить сложные структуры интерфейса на основе многоуровневых данных.
Для больших массивов рекомендуется использовать restamp
и observe:
restamp="true" полностью пересоздаёт элементы при
изменении данных, что может быть полезно для радикальных
обновлений.observe отслеживает конкретные свойства, минимизируя
лишние ререндеры.<dom-repeat>Элемент <dom-repeat> генерирует события, которые
помогают отслеживать изменения:
dom-change — вызывается при изменении элементов.dom-item-added и dom-item-removed —
отслеживают добавление и удаление элементов.Пример подписки на событие:
this.$.repeat.addEventListener('dom-change', () => {
console.log('Список обновлён');
});
<dom-repeat> на основе
массива данных.item,
index, odd, even.observe и
restamp.