Создадим простейшую структурную директиву. Добавим проект в папку src/app новый файл while.directive.ts:
Этот файл будет содержать директиву. Определим в файле следующий код:
import { Directive, Input, TemplateRef, ViewContainerRef } from "@angular/core"; @Directive({ selector: "[while]", standalone:true }) export class WhileDirective { constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { } @Input() set while(condition: boolean) { if (condition) { this.viewContainer.createEmbeddedView(this.templateRef); } else { this.viewContainer.clear(); } } }
Структурная директива должна применять декоратор Directive, в который передается название селектора директивы в квадратных скобках. В данном случае селектор - "while".
Для получения доступа к шаблону директивы применяется объект TemplateRef. Этот объект автоматически передается в конструктор через механизм
внедрения зависимостей. Кроме этого объекта в конструктор также передается объект рендерера - ViewContainerRef. Ну и с помощью применения
модификатора private
для обоих этих параметров автоматически будут создаваться локальные переменные, к которым мы затем сможем обратиться.
constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { }
С помощью входного свойства-сеттера, к которому применяется декоратор Input
, мы будем получать из вне некоторые значения, которые могут использоваться
при создании разметки html. В данном случае мы получаем извне некоторое булевое значение:
@Input() set while(condition: boolean) { if (condition) { this.viewContainer.createEmbeddedView(this.templateRef); } else { this.viewContainer.clear(); } }
Если в данном случае condition равно true, то производим рендеринг шаблона через вызов this.viewContainer.createEmbeddedView(this.templateRef);
.
В итоге на веб-странице появится элемент, к которому применяется данная директива.
В обратном случае, если condition равно false, то, наоборот, удаляем элемент из разметки с помощью вызова this.viewContainer.clear()
.
То есть по факту мы получили аналог директивы ngIf.
Далее применим директиву в главном компоненте AppComponent:
import { Component} from "@angular/core"; import {WhileDirective} from "./while.directive"; @Component({ selector: "my-app", standalone: true, imports: [WhileDirective], template:`<p *while="condition"> Первый параграф </p> <p *while="!condition"> Второй параграф </p> <button (click)="toggle()">Toggle</button>` }) export class AppComponent { condition = true; toggle(){ this.condition=!this.condition; } }
И после запуска приложения с помощью этой директивы мы сможем регулировать добавление или удаление определенного блока веб-страницы: