🦉 Обработка событий 🦉

Content

Обработка событий

В шаблоне компонента полезно иметь возможность регистрировать обработчики элементов DOM для определенных событий. Это помогает делать шаблон живым. Существует четыре различных варианта использования.

  1. Зарегистрируйте обработчик событий на узле DOM (событие pure DOM)
  2. Зарегистрируйте обработчик событий на компоненте (событие pure DOM)
  3. Зарегистрируйте обработчик событий на узле DOM (событие business DOM)
  4. Зарегистрируйте обработчик событий в компоненте (событие business DOM)

Событие pure DOM запускается непосредственно взаимодействием с пользователем (например, click).

<button t-on-click="someMethod">Что-то сделать</button>

Это будет примерно переведено в javascript следующим образом:

button.addEventListener("click", component.someMethod.bind(component));

Суффикс (в данном примере click) — это просто имя фактического события DOM.

Business-события DOM (Business DOM Events)

Событие business DOM запускается вызовом trigger для компонента.

<MyComponent t-on-menu-loaded="someMethod" />
 class MyComponent {
     someWhere() {
         const payload = ...;
         this.trigger('menu-loaded', payload);
     }
 }

Вызов trigger генерирует OwlEvent, дочерний класс CustomEvent с дополнительным атрибутом originalComponent (компонент, который инициировал событие). Сгенерированное событие относится к типу menu-loaded и отправляет его элементу DOM компонента (this.el). Событие всплывает и может быть отменено. Родительский компонент, прослушивающий событие menu-loaded, будет получать payload в своем обработчике someMethod (в свойстве detail события) всякий раз, когда событие инициируется.

 class ParentComponent {
     someMethod(ev) {
         const payload = ev.detail;
         ...
     }
 }

По соглашению мы используем кebab-сase для названия business событий.

Директива t-on позволяет предварительно связать свои аргументы. Например,

<button t-on-click="someMethod(expr)">Что-то сделать</button>

Здесь expr — допустимое выражение Owl, оно может быть true или какой либо переменной из контекста рендеринга.

Подсказки типов (Type Hinting)

Обратите внимание, что если вы работаете с Typescript, метод trigger является общи типом с типм payload объекта.

Затем вы можете описать тип события, что позволит увидеть ошибки типов...

this.trigger<MyCustomPayload>("my-custom-event", payload);
myCustomEventHandler(ev: OwlEvent<MyCustomPayload>) { ... }

Встроенные обработчики событий

Можно также напрямую указать встроенные выражения. Например,

<button t-on-click="state.counter++">Счетчик приращений</button>

Здесь state должно быть определено в контексте рендеринга (обычно в компоненте), что может быть переведено примерно так:

button.addEventListener("click", () => {
  context.state.counter++;
});

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

<button t-on-click="value = 1">Set value to 1 (does not work!!!)</button>
<button t-on-click="state.value = 1">Set state.value to 1 (work as expected)</button>

Модификаторы

Чтобы удалить детали событий DOM из обработчиков событий (например, вызовы event.preventDefault) и позволить им сосредоточиться на логике обработки данных, модификаторы можно указать в качестве дополнительных суффиксов директивы t-on.

МодификаторОписание
.stopвызывает event.stopPropagation() перед вызовом метода
.preventвызывает event.preventDefault() перед вызовом метода
.selfвызывает метод, только если event.target является самим элементом
.captureпривязать обработчик событий в режиме capture.
<button t-on-click.stop="someMethod">Что-то сделать</button>

Обратите внимание, что модификаторы можно комбинировать (например, t-on-click.stop.prevent), и порядок может иметь значение. Например, t-on-click.prevent.self предотвратит все клики, а t-on-click.self.prevent предотвратит клики только на самом элементе.

Наконец, допускаются пустые обработчики, поскольку они могут быть определены только для применения модификаторов. Например,

<button t-on-click.stop="">Что-то сделать</button>

Это просто остановит распространение события.