Angular

Директивы: атрибутивные и host

Подсветка элемента при наведении нужна в карточках, кнопках, строках таблицы - в десятках мест. Копировать обработчики mouseenter и стили в каждый компонент означает плодить дублирование. Директива решает это иначе: она инкапсулирует поведение и навешивается на любой элемент одним атрибутом. Написал директиву highlight один раз - и приклеиваешь её куда угодно, не меняя сам элемент. Так Angular добавляет поведение без создания нового компонента.

  • Подсветка и тултипы: одна директива добавляет поведение на любой элемент через атрибут
  • Автофокус: директива ставит фокус в поле при появлении, переиспользуется во всех формах
  • Контроль доступа: директива скрывает или отключает элемент в зависимости от роли пользователя
  • Маски ввода и форматирование: директива перехватывает ввод в поле и приводит его к нужному виду
  • Angular Material и CDK: огромная часть библиотеки это директивы поведения, а не компоненты

Предварительные знания

  • Урок ng-04: привязки свойств и событий
  • Урок ng-03: декоратор и selector компонента
  • Базовое понимание DOM-событий: click, mouseenter, input
  • Идея внедрения зависимостей через inject на уровне знакомства

Атрибутивная директива

Директива похожа на компонент, но без собственного шаблона. Она помечается декоратором @Directive и навешивается на существующий элемент через selector в виде атрибута. Задача директивы - добавить элементу поведение: реагировать на события, менять стиль, перехватывать ввод. Сам элемент остаётся прежним, директива лишь дополняет его.

Селектор [appHighlight] в квадратных скобках означает атрибут: директива срабатывает на любом элементе с этим атрибутом. Через inject(ElementRef) директива получает ссылку на DOM-элемент, к которому прикреплена. Чтобы директива стала доступна в шаблоне, её, как и компонент, добавляют в массив imports.

  • Компонент — Имеет свой шаблон и создаёт собственную разметку. Это новый кусок интерфейса
  • Атрибутивная директива — Шаблона нет. Добавляет поведение существующему элементу, не создавая разметки

Прямое обращение к nativeElement через стиль показано для простоты. На практике для манипуляций предпочтительнее host-привязки, разбираемые дальше: они декларативны и работают корректно при SSR, где DOM может отсутствовать.

Чем атрибутивная директива принципиально отличается от компонента?

Привязки и слушатели через host

Элемент, на котором висит директива, называют host (носитель). Объект host в декораторе декларативно описывает, что директива делает с этим элементом: какие свойства и атрибуты привязать и какие события слушать. Ключи в квадратных скобках - привязки свойств, в круглых - слушатели событий. Это тот же синтаксис, что и в шаблонах.

Здесь привязка [style.background] меняет фон в зависимости от сигнала active, а слушатели mouseenter и mouseleave переключают этот сигнал. Поведение полностью декларативно: никакого ручного addEventListener и обращения к nativeElement. Директива переиспользуется на любом элементе одним атрибутом appHighlight.

В объекте host строковые значения без скобок задают статические атрибуты, например 'class': 'card'. Квадратные скобки делают привязку динамической, а круглые - слушателем события. Эта симметрия совпадает с привязками в шаблоне, поэтому отдельный синтаксис учить не нужно.

Что описывает объект host в декораторе директивы?

Композиция через hostDirectives

Иногда компоненту или директиве нужно вобрать поведение нескольких готовых директив, не повторяя их код. Для этого служит hostDirectives: в декораторе перечисляются другие директивы, и их поведение автоматически применяется к носителю. Это композиция вместо наследования - предпочтительный способ переиспользования в Angular.

Теперь FancyButton автоматически получает подсветку из Highlight и поведение тултипа из Tooltip без копирования их кода. Можно даже пробросить входы и выходы вобранных директив наружу, чтобы родитель управлял ими через FancyButton. Так из мелких поведенческих кирпичиков собираются богатые компоненты.

Особняком стоят структурные директивы - те, что меняли структуру DOM через звёздочку, как *ngIf и *ngFor. В современном Angular их ниша почти полностью закрыта встроенным control flow: @if, @for и @switch делают то же самое, но быстрее и без импортов. Писать собственные структурные директивы теперь нужно крайне редко.

ТипЧто делаетСтатус в 2026
АтрибутивнаяПоведение на существующем элементеАктивно используется
Структурная (*)Меняла структуру DOMЗаменена встроенным control flow
hostDirectivesКомпозиция поведенияСовременный способ переиспользования

Что позволяет hostDirectives и что произошло со структурными директивами?

Связь с другими темами

Директивы дополняют элементы и компоненты поведением:

  • Шаблоны и привязки — Директивы используют тот же синтаксис привязок свойств и событий
  • Встроенный control flow — Структурные директивы прошлого заменены на @if и @for
  • Связь компонентов — Директивы навешиваются на проецируемые элементы, расширяя их поведение

Итог

  • Атрибутивная директива - класс с декоратором @Directive, добавляющий поведение элементу без своего шаблона
  • Объект host в декораторе задаёт привязки свойств, атрибутов и слушатели событий на самом элементе-носителе
  • Через inject директива получает ссылку на свой элемент и реагирует на события вроде наведения или клика
  • hostDirectives позволяет компоненту или директиве вобрать поведение других директив - это композиция
  • Структурные директивы со звёздочкой больше почти не нужны: их нишу закрыл встроенный control flow @if и @for

Связанные уроки

  • ng-04-templates-binding — Директивы используют те же привязки свойств и событий, что разобраны в шаблонах
  • ng-05-control-flow — Структурные директивы *ngIf и *ngFor заменены встроенным control flow
Директивы: атрибутивные и host

0

1

Войти