Angular поддерживает механизм привязки, благодаря которому различные части шаблона могут быть привязаны к некоторым значениям, определенным в компоненте.
В Angular есть следующие формы привязки данных:
Привязка элемента DOM к значению компонента (односторонняя). В двойных фигурных скобках указывается выражение, к которому идет привязка: {{выражение}}
. Например:
<h1>Добро пожаловать {{name}}!</h1>
Привязка свойства элемента DOM к значению компонента (односторонняя). Например:
<input type="text" [value]="name" />
Привязка метода компонента к событию в DOM (генерация события в DOM вызывает метод на компоненте)(односторонняя). Например:
<button (click)="addItem(text, price)">Добавить</button>
Двусторонняя привязка, когда элемент DOM привязан к значению на компоненте, при этом изменения на одном конце привязки сразу приводят к изменениям на другом конце. Например:
<input [(ngModel)]="name" placeholder="name">
Привязка к атрибуту элемента html
Привязка к классу CSS
Привязка к стилю элемента html
Первый вид привязки заключается в использовании фигурных скобок, в которые передается значение из компонента. Например, пусть у нас будет определен следующий компонент:
import { Component } from "@angular/core"; @Component({ selector: "my-app", standalone: true, 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", standalone: true, 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, но такое соответствие бывает не всегда. В этом случае мы можем использоать выражение:
[attr.название_атрибута]="значение"
После префикса attr
через точку идет название атрибута.
Обычно подобная привязка применяется к атрибутам элементов aria, svg и table. Например, тот же атрибут value поля ввода также может использовать привязку к атрибутам:
import { Component } from "@angular/core"; @Component({ selector: "my-app", standalone: true, template: `<input [attr.value]="text" />` }) export class AppComponent{ text="Hello Metanit.com"; }
Здесь атрибут value привязан к переменной text.
Привязка к событию позволяет связать с событием элемента метод из компонента:
import { Component } from "@angular/core"; @Component({ selector: "my-app", standalone: true, 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", standalone: true, 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"; import { FormsModule } from '@angular/forms'; @Component({ selector: "my-app", standalone: true, imports:[FormsModule], // импортируем FormsModule для двусторонней привязки template: `<p>Привет {{name}}</p> <input type="text" [(ngModel)]="name" /> <br><br> <input type="text" [(ngModel)]="name" />` }) export class AppComponent { name ="Tom"; }
Здесь к свойству name класса AppComponent привязаны сразу три элемента: параграф и два текстового поля. Текстовые поля связаны со свойством name двусторонней привязкой.
Для ее создания применяется выражение [(ngModel)]="выражение"
.
Но стоит отметить, что, чтобы применять двустороннюю привязку к полям формы, необходимо импортировать в компонент модуль FormsModule
В итоге изменения в текстовом поле будут сказываться на тексте во втором текстовом поле и параграфе:
Привязка к классу CSS имеет следующую форму:
[class.имя_класса]="true/false"
После префикса class
через точку указывается имя класса, которое мы хотим добавить или удалить. Причем привязка идет к логическому значению.
Если равно true, то класс применяется, если false - то класс не применяется. Например:
import { Component} from "@angular/core"; import { FormsModule} from '@angular/forms'; @Component({ selector: "my-app", standalone: true, imports:[FormsModule], template: `<div [class.redbox]="isRed"></div> <div [class.redbox]="!isRed"></div> <input type="checkbox" [(ngModel)]="isRed" />`, styles: [` div {width:50px; height:50px; border:1px solid #ccc} .redbox{background-color:red;} `] }) export class AppComponent{ isRed = false; }
В данном случае идет привязка переменной isRed к классу redbox, который устанавливает красный цвет фона. У первого блока div усстанавливается класс, если переменая имеет значение true:
[class.redbox]="isRed"
. У второго блока, наоборот, если у переменной значение false: [class.redbox]="!isRed"
. Используя двустороннюю привязку к переменной isRed в элементе checkbox,
мы можем изменить ее значение.
Стоит отметить, что мы также можем использовать привязку свойств для установки класса:
import { Component} from "@angular/core"; @Component({ selector: "my-app", standalone: true, template: `<div [class]="red"></div>`, styles: [` div {width:50px; height:50px; border:1px solid #ccc} .redbox{background-color:red;} `] }) export class AppComponent{ red = "redbox" }
Привязка стилей имеет следующий синтаксис:
[style.стилевое_свойство]="выражение ? A : B"
После префикса style через точку идет название свойства стиля. В качестве значения передается некоторое выражение: если оно возвращает true, то стилевому свойству присваивается значение A; если оно возвращает false, то стилевому свойству присваивается значение B. Например:
import { Component} from "@angular/core"; import { FormsModule} from '@angular/forms'; @Component({ selector: "my-app", standalone: true, imports:[FormsModule], 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
, то есть вместо дефиса переводить следующий символ в верхний регистр.