Создание атрибутивных директив

Последнее обновление: 13.11.2023

Атрибутивные директивы меняют поведение элемента, к которому они применяются. Например, директива ngClass позволяет установить для элемента класс CSS. При этом сама директива применяется к элементу в виде атрибута:

<div [ngClass]="{verdanaFont:true}">

И при необходимости мы можем сами создавать какие-то свои директивы атрибутов для каких-то определенных целей. Итак, создадим свою директиву. Добавим в папку src/app новый файл, который назовем bold.directive.ts:

Создание директив в Angular и Typescript

Определим в файле 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],

И если мы запустим приложение, то увидим применение директивы к первому параграфу:

Создание атрибутивных директив в Angular 17

Для управления стилизацией элемента выше этот элемента извлекался через объект 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 представляет сервис, который также при вызове директивы автоматически передается в ее конструктор, и мы можем использовать данный сервис для стилизации элемента. А результат работы будет тот же, что и выше.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850