Event-driven архитектура

Event-driven (событийно-ориентированная) архитектура является ключевым элементом разработки современных веб-приложений на Marko. Она позволяет компонентам взаимодействовать через события, минимизируя прямые зависимости и упрощая управление состоянием.

Компоненты и события

В Marko каждый компонент может быть самостоятельным модулем с собственным состоянием и поведением. Компоненты обмениваются данными через события, что обеспечивает слабое связывание между ними. Основные методы работы с событиями:

  • $emit — отправка события из компонента.
  • on — подписка на событие в родительском или соседнем компоненте.
  • once — одноразовая подписка, событие обрабатывается один раз.

Пример отправки события:

this.emit('userLoggedIn', { id: 123, name: 'Иван' });

Подписка на событие:

this.on('userLoggedIn', (user) => {
    console.log(`Пользователь вошёл: ${user.name}`);
});

Поток данных и управление состоянием

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

  1. Пользователь или система инициирует событие.
  2. Компонент-эмиттер отправляет событие.
  3. Все подписанные компоненты получают уведомление и обновляют своё состояние.

Такой подход предотвращает «жёсткую» связку компонентов и уменьшает вероятность возникновения ошибок при изменении структуры приложения.

Встроенные события Marko

Marko предоставляет ряд встроенных событий, которые облегчают обработку жизненного цикла компонентов:

  • mount — срабатывает при монтировании компонента в DOM.
  • update — срабатывает при обновлении состояния компонента.
  • destroy — срабатывает перед удалением компонента из DOM.

Пример использования:

on('mount', () => {
    console.log('Компонент смонтирован');
});

on('update', (state) => {
    console.log('Состояние обновлено', state);
});

Кастомные события и родительские компоненты

Компоненты могут отправлять кастомные события родительским компонентам, позволяя централизованно управлять бизнес-логикой. Это особенно полезно в сложных интерфейсах с множеством взаимодействующих модулей.

Пример передачи кастомного события родителю:

<MyButton on-clicked("handleButtonClick") />
handleButtonClick(event) {
    console.log('Кнопка нажата', event);
}

В этом примере событие clicked внутри MyButton автоматически вызывает метод родителя handleButtonClick.

Асинхронные события

Marko поддерживает асинхронную обработку событий, что позволяет безопасно работать с API и другими внешними источниками данных. Асинхронные функции можно использовать как обработчики событий:

this.on('fetchData', async () => {
    const data = await fetch('/api/data').then(res => res.json());
    this.setState({ data });
});

Асинхронные события интегрируются с жизненным циклом компонентов и не блокируют интерфейс, сохраняя отзывчивость приложения.

Лучшие практики

  • Минимизировать прямые ссылки на компоненты. Использовать события для передачи данных.
  • Использовать одноразовые события (once) для операций, которые не должны повторяться.
  • Избегать глубоких цепочек событий, чтобы не усложнять отладку и трассировку.
  • Использовать именование событий осмысленно, чтобы сразу понимать контекст и источник события.

Event-driven архитектура в Marko обеспечивает гибкость, масштабируемость и чистую организацию кода. Правильное использование событий позволяет строить сложные интерфейсы без хаоса в связях между компонентами.