Angular поддерживает механизм привязки, благодаря которому различные части шаблона могут быть привязаны к некоторым значениям, определенным в компоненте.
В Angular есть четыре формы привязки данных:
<h1>Добро пожаловать {{name}}!</h1>
<input type="text" [value]="name" />
<button (click)="addItem(text, price)">Добавить</button>
<input [(ngModel)]="name" placeholder="name">
Первый вид привязки заключается в использовании фигурных скобок, в которые передается значение из компонента. Например, пусть у нас будет определен следующий компонент:
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: `<p>Имя: {{name}}</p> <p>Возраст: {{age}}</p>` }) export class AppComponent { name = "Tom"; age = 25; }
И при запуске приложения выражения типа name будут автоматически заменяться соответствующими значениями, определенными в компоненте:
И если в процессе работы приложения свойства name и age в компоненте изменят свое значение, то также изменится значение в разметке html, которая привязана к этим свойствам.
Мы можем привязать значение к свойству элемента html. В этом случае свойство указывается в квадратных скобках:
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: `<input type="text" [value]="name" />` }) export class AppComponent { name = "Tom"; }
Важно понимать, что здесь идет привязка не к атрибуту, а именно к свойству элемента в javascript, который представляет данный элемент html. То есть html-элемент <input> в javascript представлен интерфейсом HTMLInputElement, у которого есть свойство value.
Но в данном случае мы могли бы написать и так:
template: `<input type="text" value="{{name}}" />`
И в этом случае мы передаем значение с помощью интерполяции атрибуту элемента.
Или другой пример:
template: `<p [textContent]="name"></p>`
У html-элемента <p> нет атрибута textContent. Зато у интерфейса Node, который представляет данный элемент DOM, есть свойство textContent, к которому мы можем осуществить привязку.
Иногда возникает необходимость выполнить привязку не к свойству, а именно к атрибуту html-элемента. Хотя свойства и атрибуты html-элементов могут пересекаться, как это было показано выше в примере с свойством/атрибутом value, но такое соответствие бывает не всегда. В этом случае мы можем использоать выражение:
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<table border="1"> <tr><td [attr.colspan]="colspan">One-Two</td></tr> <tr><td>Three</td><td>Four</td></tr> <tr><td>Five</td><td>Six</td></tr> </table>` }) export class AppComponent{ colspan=2; }
Привязка к событию позволяет связать с событием элемента метод из компонента:
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: `<p>Количество кликов {{count}}</p> <button (click)="increase()">Click</button>` }) export class AppComponent { count: number=0; increase() : void { this.count++; } }
В шаблоне определен элемент button, у которого есть событие click. Для обработки этого события в классе AppComponent определен метод increase(), который увеличивает количество условных кликов. В итоге при нажатии на кнопку сработает данный метод:
В качестве альтернативы мы могли бы установить привязку к событию так:
template: `<p>Количество кликов {{count}}</p> <button on-click="increase()">Click</button>`
После префикса on через дефис идет название события.
Мы также можем передавать информацию о событии через объект $event:
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: `<p>Количество кликов {{count}}</p> <button (click)="increase($event)">Click</button>` }) export class AppComponent { count: number=0; increase($event : any) : void { this.count++; console.log($event); } }
$event - это встроенный объект, через который Angular передает информацию о событии.
Двусторонняя привязка позволяет динамически менять значения на одном конце привязки при изменениях на другом конце. Как правило, двусторонняя привязка применяется при работе с элементами ввода, например, элементами типа input. Например:
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: `<p>Привет {{name}}</p> <input type="text" [(ngModel)]="name" /> <br><br> <input type="text" [(ngModel)]="name" />` }) export class AppComponent { name:string="Tom"; }
Здесь к свойству name класса AppComponent привязаны сразу три элемента: параграф и два текстового поля. Тектовые поля связаны со свойством name двусторонней привязкой. Для ее создания применяется выражение [(ngModel)]=«выражение».
В итоге изменения в текстовом поле будут сказываться на тексте во втором текстовом поле и параграфе:
Привязка к классу CSS имеет следующую форму:
[class.имя_класса]="true/false"
После префикса class через точку указывается имя класса, которое мы хотим добавить или удалить. Причем привязка идет к логическому значению. Если равно true, то класс применяется, если false - то класс не применяется. Например:
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<div [class.isredbox]="isRed"></div> <div [class.isredbox]="!isRed"></div> <input type="checkbox" [(ngModel)]="isRed" />`, styles: [` div {width:50px; height:50px; border:1px solid #ccc} .isredbox{background-color:red;} `] }) export class AppComponent{ isRed = false; }
В данном случае идет привязка переменной isRed к классу isredbox, который устанавливает красный цвет фона. У первого блока div усстанавливается класс, если переменая имеет значение true: [class.isredbox]=«isRed». У второго блока, наоборот, если у переменной значение false: [class.isredbox]=«!isRed». Используя двустороннюю привязку к переменной isRed в элементе checkbox, мы можем изменить ее значение.
Стоит отметить, что мы также можем использовать привязку свойств для установки класса:
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<div [class]="red"></div>`, styles: [` div {width:50px; height:50px; border:1px solid #ccc} .isredbox{background-color:red;} `] }) export class AppComponent{ red = "isredbox" }
Привязка стилей имеет следующий синтаксис:
[style.стилевое_свойство]="выражение ? A : B"
После префикса style через точку идет название свойства стиля. В качестве значения передается некоторое выражение: если оно возвращает true, то стилевому свойству присваивается значение A; если оно возвращает false, то стилевому свойству присваивается значение B. Например:
import { Component} from '@angular/core'; @Component({ selector: 'my-app', template: `<div [style.backgroundColor]="isRed? 'red' : 'green'"></div> <div [style.background-color]="!isRed ? 'red' : 'green'"></div> <input type="checkbox" [(ngModel)]="isRed" />`, styles: [` div {width:50px; height:50px; border:1px solid #ccc} `] }) export class AppComponent{ isRed = false; }
Выражение [style.backgroundColor]=«isRed? 'red' : 'green'» указывает, что если переменная isRed равна true, то стилевому свойству background-color передается красный цвет, иначе передается зеленый цвет. Причем можно писать как style.background-color, так и style.backgroundColor, то есть вместо дефиса переводить следующий символ в верхний регистр.
Ссылочная переменная шаблона - это ссылка на элемент или директиву DOM в шаблоне. Используя ссылочную переменную шаблона, мы получаем доступ к значениям свойств элемента DOM. Ссылочная переменная шаблона объявляется с использованием префикса # и ref-, например #myVar и ref-myVar.
Мы можем использовать ссылочную переменную шаблона двумя способами.
<input type="text" #myVar>
<input type="text" ref-myVar>
Здесь myVar будет ссылочной переменной шаблона.
<input type="text" #mobile placeholder="Enter Mobile Number">
В текстовом поле ввода выше #mobile - это ссылочная переменная шаблона. Чтобы получить свойства DOM, мы делаем следующее.
<input type="text" #mobile (input) = "onKeyUp(mobile.value)" />
Посмотрите на фрагмент кода: #mobile- это ссылочная переменная шаблона. Доступ к выбранному значению поля выбора можно получить через mobile.value.
Теперь мы обсудим, как получить доступ к директиве NgForm с помощью ссылочной переменной шаблона. Здесь мы создаем образец формы.
import { Component } from '@angular/core'; import {NgForm} from "@angular/forms"; @Component({ selector: 'app-root', template: ` <form (ngSubmit)="onSubmitPersonForm(myForm)" #myForm="ngForm"> <input name="name" required [(ngModel)]="person.pname"> <button type="submit" [disabled]="!myForm.form.valid">Submit</button> </form>` }) export class AppComponent { person = { pname: '' } onSubmitPersonForm(form:NgForm){ console.log('submit', form); } }
Здесь мы используем ссылочную переменную шаблона для ngForm как # myForm = 'ngForm'. Теперь мы можем использовать myForm вместо ngForm, например, для проверки действительности формы, и мы также можем использовать его в наших выражениях angular.