JavaRush /Курсы /Модуль 4: Node.js, Next.js и Angular /Директивы в Angular: что это, виды директив

Директивы в Angular: что это, виды директив

Модуль 4: Node.js, Next.js и Angular
14 уровень , 0 лекция
Открыта

1. Знакомство с директивами в Angular

Директива — это специальная инструкция для Angular, которая говорит ему: “Вот этому элементу или компоненту нужно добавить особое поведение или изменить его внешний вид”.

Если проводить аналогию с HTML, то обычные атрибуты типа disabled, hidden, class — это простые “подсказки” для браузера. А директивы Angular — это такие “супер-атрибуты”, которые могут менять DOM, реагировать на события, управлять структурой страницы и даже внедрять свою бизнес-логику.

Пример:

<button *ngIf="isLoggedIn">Выйти</button>

Выглядит как обычный HTML, но *ngIf — это уже директива! Она решает: показывать этот <button> или не показывать, в зависимости от значения переменной isLoggedIn.

Директивы — это не компоненты

  • Компонент — всегда связан с шаблоном (HTML+CSS) и обычно “рисует” кусок интерфейса.
  • Директива — не имеет собственного шаблона. Она “вешается” на существующий HTML-элемент и меняет его поведение или внешний вид.

Интересный факт: Любой Angular-компонент — это тоже директива, но с шаблоном! Когда вы пишете @Component, это на самом деле расширяет @Directive.

2. Виды директив в Angular

В Angular есть три основных типа директив. Давайте разберем их по порядку:

Тип директивы Пример Описание
Атрибутивная
[ngClass]
,
[ngStyle]
,
appHighlight
Меняет поведение или внешний вид существующего элемента.
Структурная
*ngIf
,
*ngFor
,
*ngSwitch
Меняет структуру DOM: добавляет, удаляет или перемещает элементы.
Компонент
<app-user-card>
Директива с шаблоном (то есть компонент).

Атрибутивные директивы

Атрибутивная директива изменяет внешний вид или поведение того элемента, к которому она применена.

Примеры:

  • [ngClass] — динамически добавляет или убирает CSS-классы.
  • [ngStyle] — динамически меняет стили.
  • appHighlight — ваша собственная директива, которая, например, подсвечивает элемент.

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

<p [ngClass]="{ 'important': isImportant }">Важное сообщение</p>

Если isImportant === true, класс important добавится к <p>.

Структурные директивы

Структурная директива меняет саму структуру DOM: может добавить, удалить или клонировать элементы.

Признак: Всегда начинается со звёздочки *.

Примеры:

  • *ngIf — показывает/скрывает элемент.
  • *ngFor — повторяет элемент для каждого значения в массиве.
  • *ngSwitch — реализует “переключатель” между разными шаблонами.

Пример:

<ul>
  <li *ngFor="let user of users">{{user.name}}</li>
</ul>

Если массив users содержит 5 пользователей, то <li> будет 5 штук!

Компоненты (директивы с шаблоном)

Компонент — это директива, у которой есть собственный шаблон, стили и логика. На практике, когда говорят “директивы”, обычно имеют в виду только атрибутивные и структурные директивы, а компоненты выделяют в отдельную категорию.

3. Как работают директивы? Немного магии Angular

Когда Angular компилирует ваш шаблон, он ищет директивы по селекторам (например, [ngClass], *ngIf или appHighlight). Если находит — “навешивает” соответствующее поведение на элемент.

  • Для атрибутивных директив Angular создаёт экземпляр класса-директивы и связывает его с элементом.
  • Для структурных Angular может полностью удалить или создать DOM-элемент на лету.

Пример жизненного цикла:

  1. Angular видит <p appHighlight>Текст</p>.
  2. Создаёт экземпляр директивы HighlightDirective.
  3. Передаёт ссылку на элемент, чтобы директива могла его изменить.
  4. Если в директиве есть подписка на события — она работает, пока элемент жив.

4. Атрибутивные директивы: подробный пример

Давайте создадим свою простую атрибутивную директиву, которая будет подсвечивать элемент при наведении мышки.

Шаг 1. Генерируем директиву

В терминале:

ng generate directive highlight

Angular создаст файл highlight.directive.ts и зарегистрирует директиву.

Шаг 2. Код директивы

import { Directive, ElementRef, HostListener } from '@angular/core';

@Directive({
  selector: '[appHighlight]' // Используем как атрибут!
})
export class HighlightDirective {
  constructor(private el: ElementRef) {}

  @HostListener('mouseenter') onMouseEnter() {
    this.el.nativeElement.style.backgroundColor = 'yellow';
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.el.nativeElement.style.backgroundColor = '';
  }
}

Шаг 3. Используем директиву в шаблоне

<p appHighlight>Наведи на меня мышкой — я засвечусь!</p>

Выглядит как магия: никакого лишнего кода в компоненте, просто “украшение” HTML.

5. Структурные директивы: подробный пример

Структурные директивы всегда используют синтаксис с *. Самые популярные — *ngIf и *ngFor.

*ngIf

Показывает или скрывает элемент в зависимости от условия.

<button *ngIf="isLoggedIn">Выйти</button>

Если isLoggedIn === false, кнопки вообще не будет в DOM!

*ngFor

Повторяет элемент для каждого значения в массиве.

<ul>
  <li *ngFor="let user of users">{{user.name}}</li>
</ul>

*ngSwitch

Переключает шаблоны по значению.

<div [ngSwitch]="user.role">
  <p *ngSwitchCase="'admin'">Администратор</p>
  <p *ngSwitchCase="'user'">Пользователь</p>
  <p *ngSwitchDefault>Гость</p>
</div>

6. Полезные нюансы

Как создавать свои директивы

Angular позволяет создавать собственные директивы, чтобы переиспользовать логику и не дублировать код.

  • Атрибутивная директива
    Используется как обычный атрибут: <div appMyDirective></div>
    Реализуется как класс с декоратором @Directive.
  • Структурная директива
    Используется со звёздочкой: <div *appMyIf="условие"></div>
    Требует внедрения TemplateRef и ViewContainerRef — это чуть сложнее, но возможно!

Краткая таблица: основные директивы Angular

Директива Тип Описание
*ngIf
Структурная Показывает/скрывает элемент по условию
*ngFor
Структурная Повторяет элемент для каждого значения массива
*ngSwitch
Структурная Переключает шаблоны
[ngClass]
Атрибутивная Динамически меняет классы
[ngStyle]
Атрибутивная Динамически меняет стили
ngModel
Атрибутивная Двусторонняя привязка данных

Как Angular отличает директиву от обычного атрибута?

  • Атрибутивные директивы обычно регистрируются в декораторе @Directive с селектором в квадратных скобках: selector: '[appHighlight]'
  • Структурные директивы используют звёздочку * — Angular превращает это в специальный синтаксис под капотом (на самом деле это sugar-синтаксис для <ng-template>).

7. Типичные ошибки при работе с директивами

Ошибка №1: Путают директиву и компонент.
Новички часто думают, что директива — это “маленький компонент”. На самом деле директива не имеет своего шаблона и не рисует ничего в DOM сама по себе. Она только “влияет” на существующий элемент.

Ошибка №2: Забывают добавить директиву в imports.
Если вы создали свою директиву и не добавили её в модуль или в imports массива Standalone-компонента — Angular её не увидит и выдаст ошибку типа “unknown directive”.

Ошибка №3: Используют директиву как тег.
Атрибутивные директивы нельзя использовать как самостоятельные теги (<appHighlight></appHighlight> — ошибка!). Используйте их только как атрибуты: <div appHighlight></div>.

Ошибка №4: Применяют структурную директиву без звёздочки.
Если написать <div ngIf="isVisible"></div>, Angular не поймёт, что вы хотели, и элемент не будет работать как надо. Нужно обязательно использовать *ngIf.

Ошибка №5: Забывают про область действия директивы.
Если директива объявлена только в одном модуле, а вы пытаетесь использовать её в другом — получите ошибку. Не забудьте экспортировать директиву через exports или добавить в нужный модуль.

Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ