Перейти к содержанию

Директивы

Angular директивы используются для изменения внешнего вида или поведения DOM-элемента. Выделяют три типа директив:

  • С собственным шаблоном, или по-другому компоненты (компоненты являются директивами);
  • Структурные, которые изменяют структуру DOM-дерева;
  • Атрибуты, которые изменяют внешний вид или поведение по умолчанию элемента DOM-дерева.

Компоненты уже были разобраны ранее, поэтому в этой и следующей главах будут рассмотрены только структурные директивы и директивы атрибуты.

Несмотря на существующую классификацию, иногда бывают трудно однозначно определить принадлежность к группе, поскольку одна директива может совмещать в себе функционал сразу двух групп.

По умолчанию в Angular предусмотрен ряд встроенных директив. Рассмотрим самые популярные из них.

К встроенным структурным директивам относятся: *ngIf, *ngFor, *ngSwitch и др. Все Angular директивы этой группы предваряются символом *.

ngIf

*ngIf добавляет или удаляет элемент из DOM-дерева в зависимости от истинности переданного выражения (true — добавление, false — удаление).

1
2
<div *ngIf="true">This will be added to the DOM</div>
<div *ngIf="false">This will be removed from the DOM</div>

ngFor

*ngFor используется для визуализации массива данных. Директива применяется к блоку HTML-кода, определяющего, как должны отображаться данные элемента массива. Далее Angular использует этот HTML как шаблон для всех последующих элементов в массиве.

Предположим, имеется следующий массив данных:

1
2
3
4
5
cars: any[] = [
    {name: 'Audi', year: 2018},
    {name: 'BMW', year: 2015},
    {name: 'Mercedes', year: 2016}
];

Отображение списка в шаблоне выглядит так:

1
2
3
4
5
<ul>
    <li *ngFor="let car of cars; let i = index">
        {{i + 1}}. {{car.name}}, {{car.year}}
    </li>
</ul>

В результате будет сгенерирован следующий HTML-код:

1
2
3
4
5
<ul>
    <li>1. Audi, 2018</li>
    <li>2. BMW, 2015</li>
    <li>3. Mercedes, 2016</li>
</ul>

Angular *ngFor поддерживает ряд шаблонных переменных:

  • index — хранит порядковый номер текущего элемента массива, отсчет начинается с 0;
  • firsttrue, если элемент первый в массиве;
  • lasttrue, если элемент последний в массиве;
  • eventrue, если элемент четный;
  • oddtrue, если элемент нечетный.
  • count — хранит общее количество элементов массива

При изменении массива Angular перерисовывает дерево DOM полностью. Но если использовать функцию trackBy, то Angular будет понимать, какой элемент изменился, а затем внесёт изменения в DOM только для этого конкретного элемента.

1
2
3
4
5
6
// в шаблоне
<li *ngFor="let item of items; trackBy: trackByFn">
    {{ item }}
</li>
// в компоненте trackByFn(index, item) { return item.id; //
unique id corresponding to the item }

Если HTML-шаблон элемента массива состоит из двух DOM-элементов, находящихся на одном уровне иерархии, необходимо использовать элемент <ng-container></ng-container>, который позволяет группировать элементы. При этом сам он из шаблона будет удален.

1
2
3
4
<ng-container *ngFor="let car of cars">
    <p [textContent]="car.name"></p>
    <p [textContent]="car.year"></p>
</ng-container>

ngSwitch

ngSwitch эмулирует работу оператора switch применительно к шаблонам.

1
car: string = 'Audi';
1
2
3
4
5
6
7
<div [ngSwitch]="car">
    <p *ngSwitchCase="'Audi'">This is Audi</p>
    <p *ngSwitchCase="'BMW'">This is BMW</p>
    <p *ngSwitchCase="'Mercedes'">This is Mercedes</p>

    <p *ngSwitchDefault>Car is undefined</p>
</div>

Angular директивы *ngSwitchCase и *ngSwitchDefault отображают указанный шаблон в зависимости от значения переданной ngSwitch переменной или шаблон по умолчанию, если ни один из описанных случаев не соответствует реальному значению.

ngStyle и ngClass

К наиболее используемым директивам атрибутам относятся [ngStyle] и [ngClass].

[ngStyle] принимает объект, в котором ключами служат наименования CSS-свойств, а их значениями — возможные значения соответствующих CSS-свойств.

1
2
3
4
elementStyles: any = {
    color: 'red',
    opacity: 0.5,
};
1
<div [ngStyle]="elementStyles">Some text</div>

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

1
2
3
<div [ngStyle]="{color: 5 < 10 ? 'green' : 'red' }">
    Some text
</div>

[ngClass] также принимает объект, но ключами здесь служат наименования классов, а значениями — выражения типа Boolean. Если выражение истинно, класс будет добавлен к списку уже имеющихся классов.

В отличие от атрибута [attr.class], Angular директива [ngClass] не заменяет уже установленное значение.

1
<div [ngClass]="{'label': true}">Some text</div>

Также директива может принимать массив со списком классов, которые необходимо применить к элементу.

1
<div [ngClass]="['label', 'label-small']">Some text</div>

Ссылки

Комментарии