Polymer предоставляет мощный механизм работы с событиями, который позволяет компонентам обмениваться данными и реагировать на изменения состояния. Одним из ключевых элементов этой системы являются пользовательские события, которые выходят за рамки стандартных DOM-событий, предоставляя возможность более точного и гибкого взаимодействия между компонентами.
В Polymer пользовательское событие создаётся с помощью конструктора
CustomEvent. Основной синтаксис:
let event = new CustomEvent('имя_события', {
detail: { /* данные события */ },
bubbles: true,
composed: true
});
this.dispatchEvent(event);
detail — объект, содержащий данные,
которые передаются слушателям события. Это ключевой способ обмена
информацией между компонентами.bubbles — определяет, будет ли событие
всплывать по DOM-дереву. Если true, событие может быть
поймано родительскими элементами.composed — позволяет событию проходить
через Shadow DOM границы. Без этой опции событие останется локальным для
компонента.Внутри компонента Polymer пользовательское событие чаще всего вызывается при изменении состояния или действия пользователя:
this.dispatchEvent(new CustomEvent('user-logged-in', {
detail: { username: this.username },
bubbles: true,
composed: true
}));
Здесь событие user-logged-in может быть поймано
родительскими компонентами или любым элементом, который находится выше в
DOM-структуре.
Слушатели событий можно добавлять двумя способами: через шаблон компонента и через программный код.
1. Через шаблон
В Polymer используются специальные атрибуты для связывания событий с методами:
<my-button on-click="handleClick"></my-button>
Для пользовательских событий применяется префикс on- и
имя события в kebab-case:
<user-form on-user-logged-in="handleUserLoggedIn"></user-form>
Метод handleUserLoggedIn будет получать объект события
как аргумент:
handleUserLoggedIn(event) {
console.log(event.detail.username);
}
2. Через программный код
С помощью addEventListener событие можно отслеживать
динамически:
this.addEventListener('user-logged-in', (event) => {
console.log(event.detail.username);
});
Этот способ особенно удобен для компонентов, которые создаются динамически или когда требуется делегирование событий.
bubbles и
composedЭти два флага имеют критическое значение для взаимодействия компонентов:
true, событие
распространяется вверх по DOM-дереву. Всплытие позволяет родительским
компонентам реагировать на действия детей без прямой связи.true, событие может
покинуть Shadow DOM и быть доступным вне инкапсуляции компонента. Без
composed: true родительские элементы не увидят событие,
если компонент находится внутри Shadow DOM.Пример использования:
this.dispatchEvent(new CustomEvent('data-updated', {
detail: { newValue: this.value },
bubbles: true,
composed: true
}));
user-logged-in, data-updated.data-changed вместо data-state.click, input, change).Объект detail может содержать любую структуру данных:
объекты, массивы, примитивы. Рекомендуется использовать простые и легко
сериализуемые структуры:
this.dispatchEvent(new CustomEvent('cart-updated', {
detail: {
items: [
{ id: 1, name: 'Item A', quantity: 2 },
{ id: 2, name: 'Item B', quantity: 1 }
],
total: 300
},
bubbles: true,
composed: true
}));
Пользовательские события в Polymer позволяют строить иерархию компонентов с четко определёнными каналами связи:
<parent-component>
<child-component on-action-triggered="handleAction"></child-component>
</parent-component>
handleAction(event) {
console.log('Данные из дочернего компонента:', event.detail);
}
Таким образом, родительский компонент реагирует на события дочернего без прямого вызова методов или доступа к внутреннему состоянию дочернего элемента.
Пользовательские события часто применяются для реализации обратного связывания данных между компонентами:
this.dispatchEvent(new CustomEvent('value-changed', {
detail: { value: this.value },
bubbles: true,
composed: true
}));
Если компонент подключён через Polymer binding в родителе:
<custom-input value="{{parentValue::value-changed}}"></custom-input>
Изменение внутри дочернего элемента автоматически обновляет
переменную parentValue в родительском компоненте.
detail.Пользовательские события в Polymer обеспечивают гибкое и мощное
взаимодействие компонентов, позволяя строить сложные интерфейсы с
минимальной связностью и максимальной модульностью. Правильное
использование detail, bubbles и
composed позволяет создать надёжную систему обмена данными
между компонентами в любых условиях.