Синтаксис шаблонов Angular 2

Мы уже встречали шаблоны Angular в нескольких предыдущих главах. В этой статье мы подробно рассмотрим синтаксис Angular.

Шаблон играет роль представления; проще говоря, это часть, отображаемая пользователю.

  • HTML
  • Выражение интерполяции
  • Выражения шаблона
  • Операторы шаблона
  • Синтаксис привязки
  • Привязка свойств
  • Привязка атрибутов HTML, классов и стилей
  • Привязка событий
  • Двусторонняя привязка данных с NgModel
  • Встроенные директивы
  • * и <template>
  • Ссылочные переменные шаблона
  • Входные и выходные свойства
  • Операторы выражений шаблона

HTML

HTML — это "язык" шаблонов Angular. За исключением элемента <script>, который отключён, поддерживаются все остальные элементы HTML. Например:

<h1>Моё первое Angular-приложение</h1>


Выражение интерполяции

Синтаксис выражений интерполяции следующий:{{ ... }}。

Выражения интерполяции могут вставлять вычисленную строку в HTML, а также использоваться в качестве значений атрибутов.

<h3> {{title}} <img src="{{imageUrl}}" style="height:30px"> </h3>

Выражения шаблона

{{ ... }}На самом деле это выражение шаблона. Angular вычисляет его и преобразует в строку для вывода.

В следующем примере складываются два числа:

<!-- "Сумма 1 + 1 равна 2" --> <p>Сумма 1 + 1 равна {{1 + 1}}</p>

Мы можем использоватьgetVal(), чтобы получить значение этого выражения:

<div class="example"> <div class="example_code"> [mycode3 type="html"] <!-- "4" --> <p>{{1 + 1 + getVal()}}</p>

Шаблонные выражения аналогичны JavaScript. Многие выражения JavaScript также являются допустимыми шаблонными выражениями, но не все.

Следующие выражения JavaScript запрещены:

  • Выражения присваивания (=,+=,-=...)
  • оператор new
  • with;или'цепочки выражений
  • Операции инкремента и декремента (++и--) Другие заметные отличия от синтаксиса JavaScript включают:
  • Побитовые операторы не поддерживаются (|и&)
  • Операторы в шаблонных выражениях, такие как|и?.и т. д., получили новые значения

Привязка свойств

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

Самый распространённый способ привязки свойств задаёт свойству элемента значение свойства компонента. В следующем примере свойство src элемента изображения привязано к свойству imageUrl компонента:

<img [src]="imageUrl">

Отключить кнопку, когда компонент isUnchanged (не изменён):

<button [disabled]="isUnchanged">Кнопка отключена</button>

Установите атрибуты директивы:

<div [ngClass]="classes">[ngClass] привязан к свойству classes.</div>

Установите свойство пользовательского компонента (важный способ взаимодействия между родительским и дочерним компонентами):

<user-detail [user]="currentUser"></user-detail>

Привязка атрибутов HTML, классов и стилей

Синтаксис шаблонов предоставляет специальную форму односторонней привязки данных для сценариев, которые плохо подходят для привязки свойств.

Привязка атрибутов

Когда у элемента нет свойства для привязки, используйте привязку HTML-атрибутов.

Рассмотрите такие атрибуты, как ARIA, SVG и colspan/rowspan в таблицах. Это исключительно атрибуты. У них нет соответствующих свойств для привязки.

Следующий пример вызовет ошибку:

<tr><td colspan="{{1 + 1}}">Три-Четыре</td></tr>

Мы получим эту ошибку:

Template parse errors:
Can't bind to 'colspan' since it isn't a known native property

模板解析错误:不能绑定到'colspan',因为它不是已知的原生属性

Как говорит подсказка,<td>У элемента нетcolspanСвойство. Но интерполяционные выражения и привязка свойств могут задавать толькосвойство, а не атрибут, поэтому требуется привязка атрибутов HTML-тега для создания и привязки подобных атрибутов.

Синтаксис привязки атрибутов HTML-тега аналогичен привязке свойств, но часть в квадратных скобках — это не имя свойства элемента; вместо этого она состоит из префикса attr. и имени атрибута HTML-тега, а затем значение атрибута HTML-тега задаётся с помощью выражения, которое может вычисляться в строку. Например:

<table border=1> <tr><td [attr.colspan]="1 + 1">Один-Два</td></tr> <tr><td>Пять</td><td>Шесть</td></tr> </table>

Привязка CSS-классов

С помощью привязки CSS-классов мы можем добавлять и удалять имена CSS-классов из атрибута class элемента.

Привязка CSS-классов синтаксически похожа на привязку свойств. Но часть в квадратных скобках — это не имя свойства элемента; вместо этого она состоит из префикса class, за которым следует точка (.), а затем имя CSS-класса. Последние две части являются необязательными. Например:[class.class-name] 。

В следующем примере показано, как добавлять и удалять класс "special" с помощью привязки CSS-классов:

<!--Стандартная установка класса стиля HTML--> <div class="bad curly special">Плохой кудрявый особенный</div> <!--Сброс или переопределение классов стилей с помощью привязки--> <div class="bad curly special" [class]="badCurly">Плохой кудрявый</div> <!--Добавление или удаление класса стиля special на основе значения свойства--> <div [class.special]="isSpecial">Этот стиль особенный</div>

Привязка стилей

С помощью привязки стилей можно задавать встроенные стили. Синтаксически привязка стилей похожа на привязку свойств, но часть внутри квадратных скобок — это не имя свойства элемента; привязка стилей состоит из style., за которой следует имя CSS-свойства стиля, например: [style.style-property].

<button [style.color] = "isSpecial ? 'red': 'green'">Красный</button> <button [style.background-color]="canSave ? 'cyan': 'grey'" >Сохранить</button> <!--Привязка стилей с единицами измерения--> <button [style.font-size.em]="isSpecial ? 3 : 1" >большой</button> <button [style.font-size.%]="!isSpecial ? 150 : 50" >маленький</button>

Имена свойств стилей могут быть в kebab-case (font-size) или camelCase (fontSize).


Привязка событий

В привязке событий Angular реагирует на соответствующий поток данных — от целевого элемента представления к источнику данных — путём прослушивания действий пользователя, таких как события клавиатуры, события мыши, события касания и т. д.

Синтаксис привязки событий состоит из того, что внутри круглых скобок слева от знака равенства указываетсяцелевое событие, а внутри кавычек справа —шаблонная инструкция.

Например, следующий пример — это привязка события, которая прослушивает событие click кнопки. Всякий раз, когда выполняется щелчок мышью, вызывается метод компонентаonSave().

<button (click)="onSave()">Сохранить</button>

Имя в круглых скобках — например (click) — определяет целевое событие. В следующем примере целевым является событие click кнопки.

<button (click)="onSave()">Сохранить</button>

Вы также можете использовать форму с префиксом on-:

<button on-click="onSave()">При сохранении</button>

Двусторонняя привязка данных с NgModel

При разработке форм ввода данных желаемый результат — одновременно отображать данные компонента в форме и обновлять данные компонента, когда пользователь вносит изменения.

Ниже приведён пример использования[(NgModel)]для реализации двусторонней привязки:

<input [(ngModel)]="currentUser.firstName">

[] реализует поток данных от компонента к шаблону, () реализует поток данных от шаблона к компоненту, а объединение двух [()] реализует двустороннюю привязку.

Использование синтаксиса префиксной формы:

<input bindon-ngModel="currentUser.firstName">

Встроенные директивы

Встроенные директивы Angular включают NgClass, NgStyle, NgIf, NgFor, NgSwitch и так далее.

NgClass

Динамически добавляйте или удаляйте CSS-классы, привязываясь к NgClass.

<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'" >Этот div большой.</div>

NgStyle

NgStyle, благодаря привязке к управляющему объекту key:value, позволяет одновременно задавать множество встроенных стилей.

setStyles() { let styles = { // Имя CSS-свойства 'font-style': this.canSave ? 'italic' : 'normal', // italic 'font-weight': !this.isUnchanged ? 'bold' : 'normal', // normal 'font-size': this.isSpecial ? '24px' : '8px', // 24px }; return styles; }

Добавив привязку свойства NgStyle, которая вызывает setStyles, можно соответствующим образом задать стили элемента:

<div [ngStyle]="setStyles()">Стили этого div — курсив, нормальная насыщенность и очень крупный размер (24px).</div>

NgIf

Привязав директиву NgIf к истинному выражению, можно добавить элемент и его дочерние элементы в DOM-дерево.

<div *ngIf="currentUser">Привет,{{currentUser.firstName}}</div>

И наоборот, привязка к ложному выражению удалит элемент и его дочерние элементы из DOM-дерева. Например:

<!--Поскольку значение isActive равно false, User Detail отсутствует в DOM-дереве.--> <user-detail *ngIf="isActive"></user-detail>

NgSwitch

Когда нужно условно отобразить одно дерево элементов из набора возможных деревьев элементов, необходим NgSwitch. Angular добавит в DOM только выбранный элемент. Например:

<span [ngSwitch]="userName"> <span *ngSwitchCase="'Zhang San'">Чжан Сань</span> <span *ngSwitchCase="'Li Si'">Ли Сы</span> <span *ngSwitchCase="'Wang Wu'">Ван У</span> <span *ngSwitchCase="'Zhao Liu'">Чжао Лю</span> <span *ngSwitchDefault>Лун Да</span> </span>

[Директива], которая служит родительской директивойNgSwitchпривязан к выражению, возвращающему значение switch. В примере это значение является строкой, но может быть значением любого типа. Родительская директиваNgSwitchуправляет группой<span>дочерних элементов. Каждый<span>либо привязан к выражению с соответствующим значением, либо помечен как случай по умолчанию. В любой момент времени в DOM будет присутствовать не более одного из этих span. Если соответствующее значение этого span равно значению switch, Angular 2 добавляет этот<span>span в DOM. Если ни один span не совпадает, Angular 2 добавляет span по умолчанию в DOM. Angular 2 удаляет и уничтожает все остальные span.

Три взаимодействующие директивы:

  • ngSwitch: привязан к выражению, возвращающему значение switch
  • ngSwitchCase: привязан к выражению, возвращающему соответствующее значение
  • ngSwitchDefault: атрибут, используемый для пометки элемента по умолчанию*, но вместо этого следует использовать привязку к свойству, тогда как перед ngSwitchCase и ngSwitchDefault должно стоять*。

NgFor

Эта директива нужна, когда требуется отобразить список, состоящий из нескольких элементов. Как в примере ниже, NgFor применяется к HTML-блоку.

<div *ngFor="let user of users">{{user.fullName}}</div>

NgFor также можно применить к элементу компонента, например:

<user-detail *ngFor="let user of users" [user]="user"></user-detail>

Директива ngFor поддерживает необязательный индекс, который увеличивается от 0 до длины массива во время итерации.

Этот индекс можно захватить через входную переменную шаблона и использовать в шаблоне. В примере ниже индекс сохраняется в переменную с именем i.

<div *ngFor="let user of users; let i=index">{{i + 1}} - {{user.fullName}}</div>

NgForTrackBy

Директива ngFor иногда может работать неэффективно, особенно в больших списках. Небольшое изменение, удаление или добавление элемента приводит к каскадным операциям с DOM.

Например, при обновлении контактов путем повторной выборки с сервера обновленный список может содержать многие (если не все) контакты, которые отображались ранее. Но что касается Angular, он не знает, какие из них существовали раньше, поэтому он может только очистить старый список, отбросить эти DOM-элементы и построить новый список с новыми DOM-элементами.

Чтобы решить эту проблему, можно использовать функцию отслеживания, чтобы избежать этих неудобств. Функция отслеживания сообщает Angular: мы знаем, что два объекта с одинаковым user.id — это один и тот же контакт. Например:

trackByUsers(index: number, user: User){return user.id}

Затем установите директиву NgForTrackBy для этой функции отслеживания:

<div *ngFor="let user of users; trackBy:trackByUsers">({{user.id}}) {{user.fullName}}</div>

Функция отслеживания не предотвращает все изменения DOM. Если свойство, используемое для определения того, тот ли это контакт, изменяется, элемент DOM будет обновлен; в противном случае этот элемент DOM остается без изменений. Интерфейс списка становится более плавным и отзывчивым.


Ссылочные переменные шаблона

Ссылочные переменные шаблона — это ссылки на элементы DOM или директивы в шаблоне.

Их можно использовать с нативными элементами DOM и с компонентами Angular — фактически они работают с любым пользовательским веб-компонентом.

Мы можем обращаться к ссылочным переменным шаблона на том же элементе, соседних элементах или любых дочерних элементах.

Вот два примера создания и использования ссылочных переменных шаблона:

<!--phone ссылается на элемент input и передает `value` в обработчик события--> <input #phone placeholder="номер телефона"> <button (click)="callPhone(phone.value)">Позвонить</button> <!--fax ссылается на элемент input и передает `value` в обработчик события--> <input ref-fax placeholder="номер факса"> <button (click)="callFax(fax.value)">Факс</кнопка>

Префикс (#) у "phone" означает, что мы собираемся определить переменную с именем phone.

Другие расширения