Атрибутивные директивы меняют поведение элемента, к которому они применяются. Например, директива ngClass
позволяет установить для элемента
класс CSS. При этом сама директива применяется к элементу в виде атрибута:
<div [ngClass]="{verdanaFont:true}">
И при необходимости мы можем сами создавать какие-то свои директивы атрибутов для каких-то определенных целей. Итак, создадим свою директиву. Добавим в папку src/app новый файл, который назовем bold.directive.ts:
Определим в файле bold.directive.ts следующий код:
import {Directive, ElementRef} from "@angular/core"; @Directive({ selector: "[bold]", standalone: true }) export class BoldDirective{ constructor(private elementRef: ElementRef){ this.elementRef.nativeElement.style.fontWeight = "bold"; } }
Директива - это обычный класс на TS, к которому применяется декоратор Directive, соответственно нам надо импортировать эту директиву из "angular/core". Кроме того, здесь импортируется класс "ElementRef". Он представляет ссылку на элемент, к которому будет применяться директива.
При применении декоратора @Directive
необходимо определить селектор CSS, с которым будет ассоциирована директива.
Селектор CSS для атрибута должен определяться в квадратных скобках. В данном случае в качестве селектора выступает [bold]
.
Также стоит обратить внимание, что директива определена как автономный компонент с использованием параметра
standalone: true
, что позволит ее импортировать в другие автономные компоненты.
Сам декоратор @Directive применяется к классу, который называется BoldDirective
. Это собственно и есть класс директивы, который определяет ее логику.
Для получения элемента, к которому применяется данная директива, в классе определен конструктор, имеющий один параметр: private elementRef: ElementRef
.
Через этот параметр Angular будет передавать или инжектировать тот элемент из шаблона, в котором применяется директива.
Поскольку параметр определен с ключевым словом private
, то для него будет создаваться одноименная приватная переменная, через которую мы можем получить объект ElementRef и
произвести с ним какие-либо манипуляции. В частности, здесь идет обращение к вложенному свойству nativeElement
, через которое у элемента
устанавливается жирный шрифт:
this.elementRef.nativeElement.style.fontWeight = "bold";
Теперь возьмем код главного компонента и применим директиву:
import { Component} from "@angular/core"; import { BoldDirective} from "./bold.directive"; @Component({ selector: "my-app", standalone: true, imports: [BoldDirective], template: `<div> <p bold>Hello Angular</p> <p>Приложение Angular состоит из компонентов</p> </div>` }) export class AppComponent {}
Здесь определено два параграфа, и к первому из них применяется директива. Поскольку в коде директивы был определен селектор "[bold]", то чтобы ее применить, в коде элемента применяется данный селектор.
Но сама по себе директива не заработает. Чтобы использовать директиву, нам надо ее импортировать:
import { BoldDirective} from "./bold.directive"; @Component({ imports: [BoldDirective],
И если мы запустим приложение, то увидим применение директивы к первому параграфу:
Для управления стилизацией элемента выше этот элемента извлекался через объект ElementRef в конструкторе директивы, и у него устанавливались стилевые свойства. Однако гораздо удобнее для управления стилем использовать рендерер. Так, изменим директиву следующим образом:
import {Directive, ElementRef, Renderer2} from "@angular/core"; @Directive({ selector: "[bold]", standalone: true }) export class BoldDirective{ constructor(private elementRef: ElementRef, private renderer: Renderer2){ this.renderer.setStyle(this.elementRef.nativeElement, "font-weight", "bold"); } }
Renderer2 представляет сервис, который также при вызове директивы автоматически передается в ее конструктор, и мы можем использовать данный сервис для стилизации элемента. А результат работы будет тот же, что и выше.