Итак, в предыдущих разделах мы подготовили проект к практической работе. В данном разделе мы рассмотрим, что такое привязка данных («байндинг», от англ. binding — связывание) в Angular и как ее делать.
Привязки используются для передачи каких-либо данных из компонента в шаблон и обратно. Есть несколько типов привязок в Angular:
- Строчная интерполяция — привязка содержимого html-элемента к значению переменной из компонента. Выглядит следующим образом {{ value }}. Это односторонняя привязка, используется для того, чтобы передать переменную в компонент Angular.
- Привязка свойств (атрибутов) html-элемента. Например,
<input type="text" [value]="input.value">
В данном примере в атрибут value будет занесено значение свойства value объекта input, манипуляции над которым будут производиться в компоненте. - Привязка событий — это привязка метода определенного в компоненте к событию DOM, например к клику
<button (click)="changeData(title, price)">Изменить</button>
В этом случае при клике на кнопку будет срабатывать метод changeData() с переданными ему параметрами title и price - Также существует двусторонняя привязка. Она используется в элементах форм.
<input [(ngModel)]="title">
В таком случае изменение значения в компоненте приводит к моментальному изменению значения в шаблоне, и наоборот, если к примеру сделать это к текстовому полю шаблона, то как только будет введено какое-либо значение, оно сразу будет передаваться в компонент.
Строчная интерполяция
Протестируем первый вид привязки. Изменим код шаблона, а именно его заголовок:
<div class="container"> <div class="row"> <h3>{{ title }}</h3> <table class="table table-striped text-center"> <thead class="thead-dark">
Затем изменим файл компонента и добавим переменную title
import { Component, OnInit } from '@angular/core'; import { DataService } from '../shared/data.service'; @Component({ selector: 'app-all-products', templateUrl: './all-products.component.html', styleUrls: ['./all-products.component.css'] }) export class AllProductsComponent implements OnInit { title = 'Каталог товаров'; products = []; constructor(private dataService: DataService) { } ngOnInit() { this.products = this.dataService.products; } }
Теперь при изменении значения переменной title в компоненте, изменения также мгновенно будут отображаться в шаблоне. Попробуйте задать разные значения для переменной title и проверьте результат.
Также в такой привязке можно передавать не только переменную, а и, скажем, функцию, которая будет возвращать какое-то значение, или просто выполнять арифметические операции.
Привязка свойств и событий
Теперь сделаем второй и третий тип привязки. Добавим в разметку следующий элемент:
<div class="container"> <div class="row"> <h3 class="mr-3 mt-2">{{ title }}</h3> <div class="form-inline"> <input type="checkbox" class="mr-2" [checked]="isChecked" (click)="changeIsChecked()"> <input type="text" class="form-control mr-3" [value]="title" [disabled]="isChecked"> <button class="btn btn-primary" [disabled]="isChecked" (click)="editTitle()">Изменить</button> </div> <!-- /form-inline --> .....
Для большей наглядности привязки перенесены на новую строку.
В файле компонента сделаем следующие изменения:
... export class AllProductsComponent implements OnInit { title = 'Каталог товаров'; isChecked: boolean = true; products = []; constructor(private dataService: DataService) { } ngOnInit() { this.products = this.dataService.products; } changeIsChecked() { this.isChecked = !this.isChecked; } editTitle() { this.title = 'Новый тайтл'; } }
Теперь рассмотрим, что мы изменили.
В разметке первому input с типом checkbox мы сделали привязку к атрибуту checked и сразу же к событию click привязали выполнение метода changeIsChecked, который просто будет менять флаг isChecked на противоположное значение. По умолчанию isChecked = true, при клике на чекбоксе сработает метод changeIsChecked и сменит значение на false, при втором клике снова поменяет его на true.
Следующий input с типом text и кнопка также зависят от значения флага isChecked — если чекбокс отмечен (т.е. isChecked = true), тогда срабатывает привязка к атрибуту disabled и эти элементы отключаются. Как только вы снимите чекбокс, они станут доступны. Также к текстовому полю, к атрибуту есть привязка переменной с заголовком [value]='title'
Еще одна привязка в этом примере сделана к кнопке — при клике на кнопку срабатывает метод changeTitle() и наш заголовок меняется на ‘Новый тайтл’.
Таким же способом можно сделать и привязку к атрибуту [class] или [style]
любого тега
[class]="выражение"
— данная привязка заменит все классы заданные элементу[class.className]="выражение"
— добавляет указанный класс, можно в качестве выражения добавить функцию[style.myStyle]="выражение"
— придает css-свойству myStyle результат выполнения выражения, напримерbackgroundColor
(записывается именно в ‘кэмэл кейсе’, без дефиса). Нужно также указывать единицы измерения (например, px —[style.fontSize]="14px"
)[style.myStyle.units]="выражение"
— идентичная привязка, только тут можно указать единицы измерения в цели, а не в выражении. Например,[style.fontSize.px]="14"
Но для этих целей чаще всего используются директивы [ngClass] и [ngStyle]
, которые мы рассмотрим в следующей главе.
Двусторонняя привязка
А теперь давайте сделаем двухстороннюю привязку и будем менять заголовок на то значение, которое будем вводить в поле input.
Давайте для начала подготовим наш проект. В файле шаблона компонента нужно заменить эти строки, вместо [value] вставляем директиву [(ngModel)]
... <input type="text" class="form-control mr-3" [(ngModel)]="title" [disabled]="isChecked"> ...
Далее в файле app.module.ts нам обязательно нужно подключить FormsModule
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { AllProductsComponent } from './all-products/all-products.component'; import { DataService } from './shared/data.service' @NgModule({ declarations: [ AppComponent, AllProductsComponent ], imports: [ BrowserModule, FormsModule ], providers: [DataService], bootstrap: [AppComponent] }) export class AppModule { }
Теперь как только вы вводите значение в поле input, у вас сразу же моментально меняется заголовок. И наоборот — если изменить значение переменной title в файле компонента, то оно будет обновлено и в шаблоне. Этого же эффекта можно было бы добиться без двухсторонней привязки, но в таком случае нам нужно было бы отлавливать событие (input) и уже в зависимости от введенного значения, менять атрибут [value]. Директива [(ngModel)] упрощает работу с привязками.
Итак, вкратце:
[атрибут/свойство]="выражение"
— односторонняя привязка, данные передаются от выражения к цели (применяется для свойств и атрибутов){{ выражение }}
— привязка со строковой интерполяцией(событие)="выражение"
— круглые скобки обозначают одностороннюю привязку к событию[(ngModel)]="выражение"
— двусторонняя привязка
Добавить комментарий