Структурные директивы ngIf, ngFor, ngSwitch

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

Структурные директивы изменяют структуру DOM с помощью добавления или удаления html-элементов. Рассмотрим три структурных директивы: ngIf, ngSwitch и ngFor.

ngIf

Директива ngIf позволяет удалить или, наоборот, добавить элемент при определенном условии. Например, определим следующий компонент:

import { Component} from "@angular/core";
import {NgIf} from "@angular/common";

@Component({
    selector: "my-app",
    standalone: true,
    imports: [NgIf],
    template: `<p *ngIf="condition">
				  Привет мир
				</p>
				<p *ngIf="!condition">
				  Пока мир
				</p>
				<button (click)="toggle()">Toggle</button>`
})
export class AppComponent {
	
	condition: boolean=true;
	
	toggle(){
		this.condition=!this.condition;
	}
}

Для использования директивы надо импортировать соответствующий класс NgIf из пакета "angular/common"

В шаблоне компонента зависимости от значения свойства condition будет отображаться либо первый, либо второй параграф.

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

Мы можем задавать альтернативные выражения с помощью директивы ng-template. Так, предыдущий пример будет аналогичен следующему:

import { Component} from "@angular/core";
import {NgIf} from "@angular/common";

@Component({
    selector: "my-app",
    standalone: true,
    imports: [NgIf],
    template: `<p *ngIf="condition;else unset">
                  Привет мир
                </p>
				<ng-template #unset>  
				  <p>Пока мир</p>  
				</ng-template>   
                <button (click)="toggle()">Toggle</button>`
})
export class AppComponent {
     
    condition = true;
     
    toggle(){
        this.condition=!this.condition;
    }
}

Выражение *ngIf="condition;else unset" указывает, что если condition равно false, то срабатывает блок <ng-template #unset>.

Либо можно определить более изощренную логику. Так, изменим шаблон компонента следующим образом:

template: ` <div *ngIf="condition; then thenBlock else elseBlock"></div>   
			<ng-template #thenBlock>Then template</ng-template>  
			<ng-template #elseBlock>Else template</ng-template>    
            <button (click)="toggle()">Toggle</button>`

В данном случае, если condition равно true, то отображается блок thenBlock, иначе отображается блок elseBlock.

ngFor

Директива ngFor позволяет перебрать в шаблоне элементы массива. Например:

import { Component} from "@angular/core";
import {NgFor} from "@angular/common";

@Component({
    selector: "my-app",
    standalone: true,
    imports: [NgFor],
    template: `<ul>
				  <li *ngFor="let item of items">{{item}}</li>
				</ul>`
})
export class AppComponent {
	
	items =["Tom", "Bob", "Sam", "Bill"];
}

В качестве значения директива принимает значение перебора аля-foreach: let item of items. Каждый перебираемый элемент помещается в переменную item, которую мы можем вывести на страницу.

Директивка ngFor в Angular 17

При переборе элементов нам доступен текущий индекс элемента через переменную index, которую мы также можем использовать. Например:

<div>
	<p *ngFor="let item of items; let i = index">{{i+1}}.{{item}}</p>
</div>

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

Символ звездочки и синтаксический сахар

Можно заметить, что при использовании директив ngFor и ngIf перед ними ставится символ звездочка. По факту это не более чем синтаксический сахар, который упрощает применение директивы. Так, определение ngIf:

<p *ngIf="condition">
	Привет мир
</p>
<p *ngIf="!condition">
	Пока мир
</p>

по факту будет представлять следующий код:

<ng-template [ngIf]="condition">
	<p>
		Привет мир
	</p>
</ng-template>
<ng-template [ngIf]="!condition">
	<p>
		Пока мир
	</p>
</ng-template>

В итоге параграф и его текст перемещаются внутрь элемента <ng-template>. Сама директива помещается в тег <ng-template>, в котором применяется привязка свойства. Булевое значение привязанного свойство указывает, надо ли отображать соответствующий контент.

В итоге мы можем выбирать либо первый способ со звездочкой, который более компактный, либо второй способ с элементами ng-template.

То же самое касается и директивы ngFor:

<ul>
	<li *ngFor="let item of items">{{item}}</li>
</ul>

Этот код будет эквивалентен следующему:

<ul>
	<ng-template ngFor let-item [ngForOf]="items">
		<li>{{item}}</li>
	</ng-template>
</ul>

ngSwitch

С помощью директивы ngSwitch можно встроить в шаблон конструкцию switch..case и в зависимости от ее результата выполнения выводить тот или иной блок. Например:

import { Component} from "@angular/core";
import {NgSwitch, NgSwitchCase, NgSwitchDefault} from "@angular/common";

@Component({
    selector: "my-app",
    standalone: true,
    imports: [NgSwitch, NgSwitchCase, NgSwitchDefault],
    template: `<div [ngSwitch]="count">
				  <ng-template ngSwitchCase="1">{{count * 10}}</ng-template>
				  <ng-template ngSwitchCase="2">{{count * 100}}</ng-template>
				  <ng-template ngSwitchDefault>{{count * 1000}}</ng-template>
				</div>`
})
export class AppComponent {
	
	count = 5;
}

Директива ngSwitch в качестве значения принимает некоторое выражение. В данном случае это свойство count. В элемент ng-template помещается директива ngSwitchCase, которая сравнивает значение выражения из ngSwitch с другим выражением. Если оба выражения равны, то используется данный элемент template. Иначе выполнение переходит к следующим инструкциям ngSwitchCase. Если же ни одна из инструкций ngSwitchCase не была выполнена, то вызывается инструкция ngSwitchDefault.

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