Структурные директивы
Структурные директивы изменяют структуру DOM с помощью добавления или удаления html-элементов. Рассмотрим три основные структурные директивы: ngIf
, ngSwitch
и ngFor
.
ngIf
Директива ngIf
позволяет удалить или, наоборот, отобразить элемент при определенном условии.
<div *ngIf="showFirstBlock">
First Block
</div>
<div *ngIf="!showFirstBlock">
Second Block
</div>
Начиная с версии Angular 4.0 директива ngIf
обогатилась новыми возможностями. В частности, мы можем задавать альтернативные выражения с помощью директивы ng-template
.
<div *ngIf="showFirstBlock; else secondBlock">
First Block
</div>
<ng-template #secondBlock>
Second Block
</ng-template>
Выражение*ngIf="showFirstBlock;else secondBlock"
указывает, что если showFirstBlock
равно false
, то срабатывает блок<ng-template #secondBlock>
.
Либо можно определить более изощренную логику. Так, изменим шаблон компонента следующим образом:
<div *ngIf="showFirstBlock; then firstBlock else secondBlock"></div>
<ng-template #thenBlock>
First Block
</ng-template>
<ng-template #secondBlock>
Second Block
</ng-template>
В данном случае, если showFirstBlock
равно true
, то отображается блок firstBlock
, иначе отображается блок secondBlock
.
ngFor
Директива ngFor
позволяет перебрать в шаблоне элементы массива. Эту директивы мы уже встречали ранее.
<h2>Todo List</h2>
<ul class="todo-list">
<li *ngFor="todo of todoList" (click)="openTodo(todo)">
{{ todo.title }}
</li>
</ul>
В качестве значения директива принимает значение перебора аля-foreach: let todo of todoList
. Каждый перебираемый элемент помещается в переменную todo
, которую мы можем вывести на страницу.
При переборе элементов нам доступен текущий индекс элемента через переменную index, которую мы также можем использовать. Например:
<li *ngFor="todo of todoList; let i = $index">
{{ i + 1 }} - {{ todo.title }}
</li>
Надо учитывать, что индексация идет с нуля, поэтому, чтобы в данном случае отсчет шел с единицы, к переменной i прибавляется единица.
Символ звездочки и синтаксический сахар
Можно заметить, что при использовании директив ngFor и ngIf перед ними ставится символ звездочка. По факту это не более чем синтаксический сахар, который упрощает применение директивы. Так, определениеngIf
:
<div *ngIf="showFirstBlock">
First Block
</div>
<div *ngIf="!showFirstBlock">
Second Block
</div>
по факту будет представлять следующий код:
<template [ngIf]="showFirstBlock">
<div>
First Block
</div>
</template>
<template [ngIf]="!showFirstBlock">
<div>
Second Block
</div>
</template>
В итоге div
и его текст перемещаются внутрь элемента<template>
. Сама директива помещается в тег<template>
, в котором применяется привязка свойства. Булевое значение привязанного свойство указывает, надо ли отображать соответствующий контент.
В итоге мы можем выбирать либо первый способ со звездочкой, который более компактный, либо второй способ с элементами template
.
То же самое касается и директивы ngFor
:
<ul>
<li *ngFor="let todo of todoList">{{ todo.title }}</li>
</ul>
Этот код будет эквивалентен следующему:
<ul>
<template ngFor let-todo [ngForOf]="todoList">
<li>{{ todo.title }}</li>
</template>
</ul>
ngSwitch
С помощью директивы ngSwitch
можно встроить в шаблон конструкцию switch..case и в зависимости от ее результата выполнения выводить тот или иной блок. Например:
<div [ngSwitch]="count">
<div *ngSwitchCase="1">{{count * 10}}</div>
<div *ngSwitchCase="2">{{count * 100}}</div>
<div *ngSwitchDefault>{{count * 1000}}</div>
</div>
Директива ngSwitch
в качестве значения принимает некоторое выражение. В данном случае это свойство count
. В элемент div
помещается ngSwitchCase
, которая сравнивает значение выражения из ngSwitch
с другим выражением. Если оба выражения равны, то используется данный элемент div
. Иначе выполнение переходит к следующим условиямngSwitchCase
. Если же ни одно из условий ngSwitchCase
не было выполнено, то вызывается ngSwitchDefault
.