Встроенные директивы¶
28.02.2022
Директивы — это классы, которые добавляют дополнительное поведение к элементам в ваших приложениях Angular.
Используйте встроенные директивы Angular для управления формами, списками, стилями и тем, что видят пользователи.
Смотрите код для рабочего примера, содержащего фрагменты кода, приведенные в этом руководстве.
Ниже перечислены различные типы директив Angular:
Типы директив | Подробности |
---|---|
Components | Используется с шаблоном. Этот тип директив является наиболее распространенным. |
Директивы атрибутов | Изменяют внешний вид или поведение элемента, компонента или другой директивы. |
Структурные директивы | Изменяют компоновку DOM путем добавления и удаления элементов DOM. |
Это руководство охватывает встроенные атрибутивные директивы и структурные директивы.
Встроенные директивы атрибутов¶
Директивы атрибутов слушают и изменяют поведение других элементов HTML, атрибутов, свойств и компонентов.
Многие модули NgModule, такие как RouterModule
и FormsModule
определяют свои собственные директивы атрибутов. Наиболее распространенными директивами атрибутов являются следующие:
Общие директивы | Подробности |
---|---|
NgClass | Добавляет и удаляет набор классов CSS. |
NgStyle | Добавляет и удаляет набор стилей HTML. |
NgModel | Добавляет двустороннюю привязку данных к элементу HTML-формы. |
Встроенные директивы используют только общедоступные API. Они не имеют специального доступа к каким-либо частным API, к которым не могут обращаться другие директивы.
Добавление и удаление классов с помощью NgClass
¶
Добавьте или удалите несколько классов CSS одновременно с помощью ngClass
.
Чтобы добавить или удалить один класс, используйте class binding, а не NgClass
.
Использование NgClass
с выражением¶
Для элемента, который вы хотите стилизовать, добавьте [ngClass]
и установите его равным выражению. В данном случае isSpecial
— это булево значение true
в app.component.ts
.
Поскольку isSpecial
истинно, ngClass
применяет класс special
к <div>
.
1 2 3 4 |
|
Использование NgClass
с методом¶
-
Чтобы использовать
NgClass
с методом, добавьте метод в класс компонента.В следующем примере
setCurrentClasses()
устанавливает свойствоcurrentClasses
с объектом, который добавляет или удаляет три класса на основе состоянияtrue
илиfalse
трех других свойств компонента.Каждый ключ объекта — это имя класса CSS. Если ключ имеет значение
true
,ngClass
добавляет класс. Если ключ равенfalse
, тоngClass
удаляет класс.1 2 3 4 5 6 7 8 9 10 11
currentClasses: Record<string, boolean> = {}; /* . . . */ setCurrentClasses() { // CSS classes: added/removed // per current state of component properties this.currentClasses = { saveable: this.canSave, modified: !this.isUnchanged, special: this.isSpecial }; }
-
В шаблоне добавьте привязку свойства
ngClass
кcurrentClasses
для установки классов элемента:1 2 3 4
<div [ngClass]="currentClasses"> This div is initially saveable, unchanged, and special. </div>
Для этого случая использования Angular применяет классы при инициализации и в случае изменений. Полный пример вызывает setCurrentClasses()
изначально с ngOnInit()
и когда зависимые свойства изменяются по нажатию кнопки.
Эти шаги не являются необходимыми для реализации ngClass
.
Для получения дополнительной информации смотрите код app.component.ts
и app.component.html
.
Установка встроенных стилей с помощью NgStyle
¶
Используйте NgStyle
для установки нескольких встроенных стилей одновременно, основываясь на состоянии компонента.
-
Чтобы использовать
NgStyle
, добавьте метод в класс компонента.В следующем примере
setCurrentStyles()
устанавливает свойствоcurrentStyles
с объектом, определяющим три стиля, основываясь на состоянии трех других свойств компонента.1 2 3 4 5 6 7 8 9 10
currentStyles: Record<string, string> = {}; /* . . . */ setCurrentStyles() { // CSS styles: set per current state of component properties this.currentStyles = { 'font-style': this.canSave ? 'italic' : 'normal', 'font-weight': !this.isUnchanged ? 'bold' : 'normal', 'font-size': this.isSpecial ? '24px' : '12px' }; }
-
Чтобы установить стили элемента, добавьте свойство
ngStyle
, связывающееcurrentStyles
.1 2 3 4
<div [ngStyle]="currentStyles"> This div is initially italic, normal weight, and extra large (24px). </div>
Для этого случая использования Angular применяет стили при инициализации и в случае изменений. Для этого в полном примере вызывается setCurrentStyles()
изначально с ngOnInit()
и при изменении зависимых свойств по нажатию кнопки.
Однако эти шаги не являются необходимыми для самостоятельной реализации ngStyle
.
Смотрите код app.component.ts
и app.component.html
для этой дополнительной реализации.
Отображение и обновление свойств с помощью ngModel
¶
Используйте директиву NgModel
для отображения свойства данных и обновления этого свойства, когда пользователь вносит изменения.
-
Импортируйте
FormsModule
и добавьте его в списокimports
модуля NgModule.1 2 3 4 5 6 7 8 9 10 11 12 13
// <--- JavaScript import from Angular import { FormsModule } from '@angular/forms'; /* . . . */ @NgModule({ /* . . . */ imports: [ BrowserModule, FormsModule, // <--- import into the NgModule ], /* . . . */ }) export class AppModule {}
-
Добавьте привязку
[(ngModel)]
на элемент HTML<form>
и установите ее равной свойству, здесьname
.1 2 3 4 5
<label for="example-ngModel">[(ngModel)]:</label> <input [(ngModel)]="currentItem.name" id="example-ngModel" />
Этот синтаксис
[(ngModel)]
может установить только свойство, связанное с данными.
Чтобы настроить конфигурацию, напишите расширенную форму, которая разделяет привязку свойств и событий. Используйте property binding для установки свойства и event binding для реакции на изменения.
В следующем примере значение <input>
изменяется на заглавное:
1 2 3 4 5 |
|
Вот все варианты в действии, включая версию в верхнем регистре:
NgModel
и аксессоры значений¶
Директива NgModel
работает для элемента, поддерживаемого ControlValueAccessor. Angular предоставляет аксессоры значений для всех основных элементов HTML-форм.
Для получения дополнительной информации смотрите Forms.
Чтобы применить [(ngModel)]
к встроенному элементу, не являющемуся формой, или стороннему пользовательскому компоненту, необходимо написать аксессор значения. Для получения дополнительной информации смотрите документацию API по DefaultValueAccessor.
Когда вы пишете компонент Angular, вам не нужен аксессор значения или NgModel
, если вы называете свойства значения и события в соответствии с синтаксисом двустороннего связывания Angular.
Встроенные структурные директивы¶
Структурные директивы отвечают за верстку HTML. Они формируют или изменяют структуру DOM, как правило, путем добавления, удаления и манипулирования элементами, к которым они прикреплены.
В этом разделе представлены наиболее распространенные встроенные структурные директивы:
Общие встроенные структурные директивы | Подробности |
---|---|
NgIf | Условно создает или удаляет вложенные представления из шаблона. |
NgFor | Повторяет узел для каждого элемента в списке. |
NgSwitch | Набор директив, переключающих между альтернативными представлениями. |
Для получения дополнительной информации смотрите Структурные директивы.
Добавление или удаление элемента с помощью NgIf
¶
Добавьте или удалите элемент, применив директиву NgIf
к главному элементу.
Когда NgIf
имеет значение false
, Angular удаляет элемент и его потомков из DOM. Затем Angular утилизирует их компоненты, освобождая память и ресурсы.
Чтобы добавить или удалить элемент, привяжите *ngIf
к выражению условия, например isActive
в следующем примере.
1 2 3 4 |
|
Если выражение isActive
возвращает истинное значение, NgIf
добавляет ItemDetailComponent
в DOM. Если выражение ложно, NgIf
удаляет ItemDetailComponent
из DOM и избавляется от компонента и всех его подкомпонентов.
Более подробную информацию о NgIf
и NgIfElse
смотрите в документации NgIf API.
Защита от null
¶
По умолчанию NgIf
предотвращает отображение элемента, связанного с нулевым значением.
Чтобы использовать NgIf
для защиты <div>
, добавьте *ngIf="yourProperty"
к <div>
. В следующем примере имя currentCustomer
отображается, потому что существует currentCustomer
.
1 2 3 |
|
Однако если свойство является null
, Angular не отображает <div>
. В этом примере Angular не отображает nullCustomer
, потому что это null
.
1 2 3 |
|
Вывод списка элементов с помощью NgFor
¶
Используйте директиву NgFor
для представления списка элементов.
- Определите блок HTML, который определяет, как Angular отображает отдельный элемент.
- Чтобы перечислить элементы, назначьте сокращение
let item of items
для*ngFor
.
1 |
|
Строка "let item of items"
инструктирует Angular делать следующее:
- Хранить каждый элемент массива
items
в локальной циклической переменнойitem
. - Сделать каждый элемент доступным в шаблоне HTML для каждой итерации.
- Перевести
let item of items
в<ng-template>
вокруг основного элемента. - Повторять
<ng-template>
для каждогоitem
в списке.
Для получения дополнительной информации смотрите раздел Сокращение структурных директив раздела Структурные директивы.
Повторение компонентного представления¶
Чтобы повторить элемент компонента, примените *ngFor
к селектору. В следующем примере селектором является <app-item-detail>
.
1 2 3 4 |
|
Ссылайтесь на входную переменную шаблона, такую как item
, в следующих местах:
- В главном элементе
ngFor
. - В потомках главного элемента для доступа к свойствам элемента.
Следующий пример сначала ссылается на item
в интерполяции, а затем передает привязку к свойству item
компонента <app-item-detail>
.
1 2 3 4 5 6 |
|
Для получения дополнительной информации о входных переменных шаблона смотрите Сокращение структурных директив.
Получение index
из *ngFor
.¶
Получите index
из *ngFor
во входной переменной шаблона и используйте его в шаблоне.
В *ngFor
добавьте точку с запятой и let i=index
к сокращению. Следующий пример получает index
в переменную с именем i
и отображает его вместе с именем элемента.
1 2 3 |
|
Свойство index
контекста директивы NgFor
возвращает нулевой индекс элемента в каждой итерации.
Angular переводит эту инструкцию в <ng-template>
вокруг основного элемента, затем использует этот шаблон несколько раз для создания нового набора элементов и привязок для каждого item
в списке.
Более подробную информацию о сокращении см. в руководстве Структурные директивы.
Повторение элементов при истинности условия¶
Чтобы повторить блок HTML, когда определенное условие истинно, поместите *ngIf
в контейнерный элемент, который обертывает элемент *ngFor
.
Дополнительную информацию смотрите в разделе одна структурная директива на элемент.
Отслеживание элементов с *ngFor
trackBy
¶
Сократите количество обращений вашего приложения к серверу, отслеживая изменения в списке элементов. С помощью свойства *ngFor
trackBy
, Angular может изменять и перерисовывать только те элементы, которые изменились, вместо того, чтобы перезагружать весь список элементов.
-
Добавьте в компонент метод, возвращающий значение, которое должен отслеживать
NgFor
.В данном примере значением для отслеживания является
id
элемента.Если браузер уже отобразил
id
, Angular отслеживает его и не запрашивает сервер повторно для получения того жеid
.1
trackByItems(index: number, item: Item): number { return item.id; }
-
В сокращенном выражении установите
trackBy
на методtrackByItems()
.1 2 3
<div *ngFor="let item of items; trackBy: trackByItems"> ({{item.id}}) {{item.name}} </div>
Изменение id создает новые элементы с новыми item.id
. В следующей иллюстрации эффекта trackBy
, Reset items создает новые элементы с теми же item.id
.
- При отсутствии
trackBy
обе кнопки вызывают полную замену элементов DOM. - При использовании
trackBy
только изменениеid
вызывает замену элемента.
Размещение директивы без элемента DOM¶
Angular <ng-container>
— это группирующий элемент, который не вмешивается в стили или макет, потому что Angular не помещает его в DOM.
Используйте <ng-container>
, когда нет отдельного элемента для размещения директивы.
Вот условный параграф с использованием <ng-container>
.
1 2 3 4 5 6 7 |
|
-
Импортируйте директиву
ngModel
изFormsModule
. -
Добавьте
FormsModule
в раздел imports соответствующего модуля Angular. -
Чтобы условно исключить
<option>
, оберните<option>
в<ng-container>
.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<div> Pick your favorite hero (<label ><input type="checkbox" checked (change)="showSad = !showSad" />show sad</label >) </div> <select [(ngModel)]="hero"> <ng-container *ngFor="let h of heroes"> <ng-container *ngIf="showSad || h.emotion !== 'sad'" > <option [ngValue]="h"> {{h.name}} ({{h.emotion}}) </option> </ng-container> </ng-container> </select>
Переключение случаев с помощью NgSwitch
¶
Как и оператор JavaScript switch
, NgSwitch
отображает один элемент из нескольких возможных элементов, основываясь на условии переключения. Angular помещает в DOM только выбранный элемент.
NgSwitch
— это набор из трех директив:
Директивы NgSwitch | Подробности |
---|---|
NgSwitch | Атрибутивная директива, которая изменяет поведение сопутствующих директив. |
NgSwitchCase | Структурная директива, которая добавляет свой элемент в DOM, когда его связанное значение равно значению switch и удаляет его связанное значение, когда оно не равно значению switch. |
NgSwitchDefault | Структурная директива, которая добавляет свой элемент в DOM, когда нет выбранного NgSwitchCase . |
-
На элемент, например
<div>
, добавьте[ngSwitch]
, связанный с выражением, которое возвращает значение переключателя, напримерfeature
. Хотя значениеfeature
в этом примере является строкой, значение переключателя может быть любого типа. -
Привязка к
*ngSwitchCase
и*ngSwitchDefault
на элементах для случаев.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
<div [ngSwitch]="currentItem.feature"> <app-stout-item *ngSwitchCase="'stout'" [item]="currentItem" ></app-stout-item> <app-device-item *ngSwitchCase="'slim'" [item]="currentItem" ></app-device-item> <app-lost-item *ngSwitchCase="'vintage'" [item]="currentItem" ></app-lost-item> <app-best-item *ngSwitchCase="'bright'" [item]="currentItem" ></app-best-item> <!-- . . . --> <app-unknown-item *ngSwitchDefault [item]="currentItem" ></app-unknown-item> </div>
-
В родительском компоненте определите
currentItem
, чтобы использовать его в выражении[ngSwitch]
.1
currentItem!: Item;
-
В каждом дочернем компоненте добавьте
item
свойство ввода, который привязан кcurrentItem
родительского компонента.Следующие два фрагмента показывают родительский компонент и один из дочерних компонентов.
Остальные дочерние компоненты идентичны
StoutItemComponent
.1 2 3
export class StoutItemComponent { @Input() item!: Item; }
Директивы switch также работают со встроенными элементами HTML и веб-компонентами. Например, вы можете заменить <app-best-item>
switch case на <div>
следующим образом.
1 2 3 |
|
Что дальше¶
Информацию о том, как создавать свои собственные пользовательские директивы, смотрите в Директивы атрибутов и Структурные директивы.