Директивы в Angular — это основные строительные блоки, которые позволяют расширять HTML с помощью дополнительного функционала. Они дают возможность разработчикам изменять или добавлять поведение элементов DOM, а также создавать абстракции для повторно используемых компонентов. В этой части статьи рассматриваются основные принципы создания и использования пользовательских директив в Angular.
В Angular существует несколько типов директив:
*ngIf, *ngFor.ngClass,
ngStyle.Для создания пользовательских директив в Angular используется
@Directive декоратор.
Для того чтобы создать пользовательскую директиву, необходимо выполнить несколько шагов.
Создание файла директивы:
Создадим файл с директивой, например,
highlight.directive.ts.
import { Directive, ElementRef, Renderer2 } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef, private renderer: Renderer2) { }
ngOnInit() {
this.renderer.setStyle(this.el.nativeElement, 'background-color', 'yellow');
}
}
В этом примере создаётся директива, которая изменяет цвет фона элемента на жёлтый.
Пояснение к коду:
@Directive({ selector: '[appHighlight]' }) — это
метаданные директивы. Она будет применяться к любому элементу, у
которого есть атрибут appHighlight.ElementRef,
который предоставляет доступ к элементу DOM, и Renderer2,
который позволяет безопасно изменять его стили.ngOnInit() применяется изменение стиля через
renderer.setStyle(). Это позволяет избежать прямого доступа
к DOM, что важно для безопасности и совместимости с серверным
рендерингом.Добавление директивы в модуль:
Чтобы директива начала работать, её необходимо добавить в декоратор
@NgModule в разделе declarations.
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HighlightDirective } from './highlight.directive';
@NgModule({
declarations: [HighlightDirective],
imports: [CommonModule],
exports: [HighlightDirective]
})
export class SharedModule { }Использование директивы в шаблоне:
Теперь директива доступна для использования в шаблоне Angular-компонента. Достаточно добавить её к любому элементу в HTML-шаблоне.
<div appHighlight>
Этот текст будет выделен жёлтым фоном.
</div>Можно создавать директивы с параметрами, которые позволяют гибко управлять их поведением. Например, можно передавать значение цвета для фона.
Модификация директивы для поддержки входных параметров:
Для этого используется декоратор @Input(), который
позволяет передавать данные в директиву.
import { Directive, ElementRef, Renderer2, Input } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
@Input() appHighlight: string;
constructor(private el: ElementRef, private renderer: Renderer2) { }
ngOnInit() {
const color = this.appHighlight || 'yellow'; // Если не передан цвет, используем желтый
this.renderer.setStyle(this.el.nativeElement, 'background-color', color);
}
}Использование директивы с параметром:
В HTML-шаблоне теперь можно передавать значение цвета:
<div [appHighlight]="'lightblue'">
Этот текст будет выделен светло-голубым фоном.
</div>В Angular директивы могут также генерировать события. Для этого
используется декоратор @Output() и класс
EventEmitter.
Пример директивы с выходом:
Пусть директива будет изменять цвет фона при наведении и при этом отправлять событие.
import { Directive, ElementRef, Renderer2, HostListener, Output, EventEmitter } from '@angular/core';
@Directive({
selector: '[appHover]'
})
export class HoverDirective {
@Output() hoverChanged = new EventEmitter<boolean>();
constructor(private el: ElementRef, private renderer: Renderer2) { }
@HostListener('mouseenter') onMouseEnter() {
this.renderer.setStyle(this.el.nativeElement, 'background-color', 'orange');
this.hoverChanged.emit(true);
}
@HostListener('mouseleave') onMouseLeave() {
this.renderer.setStyle(this.el.nativeElement, 'background-color', 'transparent');
this.hoverChanged.emit(false);
}
}
В этом примере директива генерирует событие hoverChanged
при наведении и убирании мыши с элемента. С помощью
HostListener отслеживаются события mouseenter
и mouseleave.
Использование директивы с событием:
В шаблоне можно подписаться на это событие.
<div appHover (hoverChanged)="onHoverChanged($event)">
Наведите курсор, чтобы изменить цвет фона.
</div>
В методе компонента onHoverChanged можно обработать
событие:
export class AppComponent {
onHoverChanged(isHovered: boolean) {
console.log(isHovered ? 'Элемент наведён' : 'Элемент покинут');
}
}Как и компоненты, директивы в Angular имеют жизненный цикл, состоящий из различных хуков. Они позволяют отслеживать изменения состояния директивы и взаимодействовать с DOM. Некоторые из наиболее часто используемых хуков:
Пример использования жизненного цикла директивы:
import { Directive, ElementRef, Renderer2, OnInit, OnDestroy } from '@angular/core';
@Directive({
selector: '[appLog]'
})
export class LogDirective implements OnInit, OnDestroy {
constructor(private el: ElementRef, private renderer: Renderer2) { }
ngOnInit() {
console.log('Директива инициализирована');
}
ngOnDestroy() {
console.log('Директива уничтожена');
}
}
Все пользовательские директивы должны быть зарегистрированы в модуле,
чтобы их можно было использовать в компонентах. Для этого необходимо
добавить директиву в массив declarations в
@NgModule.
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LogDirective } from './log.directive';
@NgModule({
declarations: [LogDirective],
imports: [CommonModule],
exports: [LogDirective]
})
export class SharedModule { }
Создание пользовательских директив в Angular предоставляет разработчикам мощный инструмент для манипуляции DOM и создания динамичных веб-приложений. Директивы позволяют добавлять новые функциональности и улучшать интерфейсы без необходимости писать много повторяющегося кода. Применяя директивы с входными параметрами, событиями и различными жизненными циклами, можно добиться высокой гибкости и повторного использования кода.