197 lines
17 KiB
Markdown
197 lines
17 KiB
Markdown
|
---
|
|||
|
title: Data Binding
|
|||
|
localeTitle: Связывание данных
|
|||
|
---
|
|||
|
# Связывание данных
|
|||
|
|
|||
|
#### мотивация
|
|||
|
|
|||
|
Данные часто определяют внешний вид приложения. Интерпретация этих данных в пользовательский интерфейс включает в себя логику классов ( `.component.html` ) и представление шаблона ( `.component.ts` ). Угловой соединяет их через привязку данных. Подумайте о привязке данных как инструмента взаимодействия компонентов.
|
|||
|
|
|||
|
#### Компонент и шаблон
|
|||
|
|
|||
|
Компонент хранит большую часть своей логики и данных внутри своего класса, украшенного `@Component` . Этот декоратор определяет класс как компонент с шаблоном HTML. Шаблон компонента представляет класс в приложении. Фокус здесь должен быть между классом компонента и шаблоном HTML.
|
|||
|
|
|||
|
Здесь происходит привязка данных. Элементные свойства и события получают присвоенные значения. Эти значения, определенные классом компонентов, служат либо одной из двух ролей. Один из них заключается в получении данных, которые затем получает шаблон. Другая управляет событиями, испускаемыми элементом шаблона.
|
|||
|
|
|||
|
![Пример кода](https://raw.githubusercontent.com/sosmaniac-FCC/designatedata/master/image4.png)
|
|||
|
|
|||
|
Попробуйте использовать эту картинку в качестве ментальной модели для следующего раздела.
|
|||
|
|
|||
|
#### Направления привязки
|
|||
|
|
|||
|
Существует два способа привязки данных: однонаправленный и двунаправленный. Угловая технически использует только однонаправленный поток данных. Двунаправленный поток в конечном счете является однонаправленным. Это происходит в двух приложениях однонаправленного потока, один раз для каждого направления. Об этом позже.
|
|||
|
|
|||
|
Однонаправленный поток определяет одностороннее взаимодействие. Либо компонент отправляет данные в шаблон, либо шаблон выдает событие в логику компонента. Изменения данных в рамках шаблона не переносятся на класс компонента. Выделение события - это односторонняя транзакция, начинающаяся с элементов шаблона.
|
|||
|
|
|||
|
Двунаправленное означает оба направления. Это означает, что изменения в данных в логике классов или шаблоне HTML сохраняются друг с другом. Объем изменений - это представление компонента. Представление содержит класс компонента и шаблон вместе.
|
|||
|
|
|||
|
#### Свойства элемента
|
|||
|
|
|||
|
Для распознавания свойств элемента, привязанного к данным, функция Angular использует специальный синтаксис для скобок.
|
|||
|
|
|||
|
```typescript
|
|||
|
// my.component.ts
|
|||
|
@Component({
|
|||
|
templateUrl: './my.component.html'
|
|||
|
})
|
|||
|
|
|||
|
export class MyComponent {
|
|||
|
value:type = /* some value of type */;
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
```html
|
|||
|
|
|||
|
<!-- my.component.html -->
|
|||
|
<any-element [property]=“value”>innerHTML</any-element>
|
|||
|
```
|
|||
|
|
|||
|
Потерпите меня на этом.
|
|||
|
|
|||
|
`[property]` отражает свойство в узле объекта элемента объекта домена (DOM). Не путайте свойства объекта с атрибутами элемента DOM. Свойства и атрибуты часто имеют одно и то же имя и делают то же самое. Однако есть одно четкое различие.
|
|||
|
|
|||
|
Помните, что `attr` (attributes) - это одно свойство базового объекта DOM. Он объявляется в экземпляре DOM с значениями атрибутов, соответствующими определению элемента. После этого он сохраняет то же значение. У каждого свойства есть собственное поле ключа-значения в узле объекта DOM. Эти свойства являются изменяемыми после инстанцирования.
|
|||
|
|
|||
|
Знайте разницу между атрибутами и свойствами. Это приведет к лучшему пониманию того, как Angular привязывает данные к свойствам (привязка свойств). Угловые вряд ли когда-либо свяжут данные с атрибутами элемента. Исключения из этого очень редки. В последний раз: Угловое связывает данные компонента с свойствами, а не с атрибутами!
|
|||
|
|
|||
|
Возвращаясь к примеру, `[ … ]` в присваивании свойств элемента имеют особое значение. Скобки показывают, что `property` привязано к `“value”` справа от задания.
|
|||
|
|
|||
|
`value` также имеет особое значение в контексте скобок. `value` само по себе является строковым литералом. Угловой читает его и сопоставляет его значение с элементами класса компонентов. Угловое значение будет заменять значение атрибута совпадающего элемента. Это, конечно, относится к тому же классу компонентов, который размещает HTML-шаблон.
|
|||
|
|
|||
|
Однонаправленный поток данных от компонента к шаблону завершен. Элемент, сопоставленный с правом присвоения скобки, предоставляет `value` . Обратите внимание, что изменения значения элемента в классе компонента переносятся до шаблона. Это обнаружение изменений Углового на работе. Изменения в пределах шаблона не влияют на член класса компонента.
|
|||
|
|
|||
|
Key-take-out: класс компонента предоставляет данные, пока шаблон отображает его.
|
|||
|
|
|||
|
Я не упомянул, что значения данных также могут отображаться во `innerHTML` компонента. В этом последнем примере реализованы двойные фигурные скобки. Угловая распознает эти фигурные скобки и интерполирует соответствующие данные класса компонента во `innerHTML` `div` .
|
|||
|
|
|||
|
```html
|
|||
|
|
|||
|
<div>The value of the component class member 'value' is {{value}}.</div>
|
|||
|
```
|
|||
|
|
|||
|
#### Обработка событий
|
|||
|
|
|||
|
Если компонент поставляет данные, шаблон передает события.
|
|||
|
|
|||
|
```typescript
|
|||
|
// my.component.ts
|
|||
|
@Component({
|
|||
|
templateUrl: './my.component.html'
|
|||
|
})
|
|||
|
|
|||
|
export class MyComponent {
|
|||
|
handler(event):void {
|
|||
|
// function does stuff
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
```html
|
|||
|
|
|||
|
// my.component.html
|
|||
|
<any-element (event)=“handler($event)”>innerHTML</any-element>
|
|||
|
```
|
|||
|
|
|||
|
Это работает аналогично привязке свойств.
|
|||
|
|
|||
|
`(event)` относится к любому действительному типу события. Например, одним из наиболее распространенных типов событий является `click` . Он испускает, когда вы _нажимаете_ на мышь. Независимо от типа, `event` привязано к `“handler”` в примере. Обработчики событий обычно являются функциями-членами класса компонентов.
|
|||
|
|
|||
|
`( … )` являются особыми для Углового. Обозначение скобок Угловое событие ограничено правильным назначением `handler` . Само событие происходит от элемента-хозяина.
|
|||
|
|
|||
|
Когда событие испускает, оно передает объект Event в виде `$event` . `handler` сопоставляется тождественно имени `handler` функции класса компонента. Однонаправленный обмен от связанного с событиями элемента на класс компонента завершен.
|
|||
|
|
|||
|
Испускание событий из обработчика, если возможно, не влияет на элемент шаблона. В конце концов, привязка является однонаправленной.
|
|||
|
|
|||
|
#### Двунаправленное связывание
|
|||
|
|
|||
|
Формы ввода - отличный пример того, почему необходимо двунаправленное связывание. Двунаправленные привязки данных являются более дорогостоящими, чем привязки к событиям или свойствам.
|
|||
|
|
|||
|
Двунаправленная привязка данных имеет собственный модуль. Прежде чем взглянуть на это, рассмотрим следующий пример.
|
|||
|
|
|||
|
```typescript
|
|||
|
// my.component.ts
|
|||
|
@Component({
|
|||
|
templateUrl: './my.component.html'
|
|||
|
})
|
|||
|
export class MyComponent {
|
|||
|
inputValue:string = "";
|
|||
|
|
|||
|
handler(event) {
|
|||
|
this.inputValue = event.target.value;
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
```html
|
|||
|
|
|||
|
<!-- my.component.html -->
|
|||
|
<input (input)=“handler($event)” [value]=“inputValue”>
|
|||
|
```
|
|||
|
|
|||
|
Время сломать это.
|
|||
|
|
|||
|
Этот пример сочетает в себе предыдущие два. Это объясняет, почему это более дорого. Следуя логике, предположим, что пользователь вводит что-то во входной элемент. Элемент передает `input` событие `handler` класса компонента шаблона. Обработчик назначает член класса `inputValue` значению испускаемого события. Это завершает обработку / привязку события.
|
|||
|
|
|||
|
Теперь перейдем к привязке свойств. Для параметра `inputValue` было присвоено новое значение. Поскольку `inputValue` привязан к `value` входного элемента, его изменение в данных просачивается вниз в свойство `value` элемента ввода. Входной элемент `value` совпадает с `inputValue` . Это завершает привязку свойства.
|
|||
|
|
|||
|
Там у вас это есть. Двунаправленная привязка данных происходит с одновременным применением обоих приложений однонаправленного связывания. Синтаксис немного грязный.
|
|||
|
|
|||
|
К счастью, Angular обеспечивает `NgModel` для упрощения синтаксиса. Нижеприведенный пример является синонимом вышеизложенного.
|
|||
|
|
|||
|
```typescript
|
|||
|
// my.component.ts
|
|||
|
@Component({
|
|||
|
templateUrl: './my.component.html'
|
|||
|
})
|
|||
|
|
|||
|
export class MyComponent {
|
|||
|
inputValue:string = "";
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
```html
|
|||
|
|
|||
|
<!-- my.component.html -->
|
|||
|
<input [(ngModel)]=“inputValue”>
|
|||
|
```
|
|||
|
|
|||
|
`ngModel` - `ngModel` удобство. Перед использованием необходимо импортировать FormsModule в корневой каталог вашего приложения. При этом в квадрате с двунаправленной привязкой данных становится намного легче работать.
|
|||
|
|
|||
|
Чтобы укрепить все, что вы узнали, ознакомьтесь с этой фотографией из официальной [Угловой документации 1](https://angular.io/guide/architecture-components#data-binding) .
|
|||
|
|
|||
|
![Схема потока данных](https://raw.githubusercontent.com/sosmaniac-FCC/designatedata/master/image2.png)
|
|||
|
|
|||
|
Вы можете визуально суммировать все до этой точки с этой картинкой. У Angular's Documentation есть много других фотографий, которые стоит посмотреть. Этого достаточно, учитывая объем этой статьи.
|
|||
|
|
|||
|
#### Компонент к компоненту
|
|||
|
|
|||
|
Чтобы привязывать данные и события к различным компонентам, вы должны использовать декораторы @Input и @Output. Угловые компоненты находятся в частном порядке. Ни один из компонентов компонента не доступен нигде вне своего собственного вида.
|
|||
|
|
|||
|
Декодер @Input указывает, что значение элемента получено из родительской функции. Для этого лучше визуализировать визуализацию.
|
|||
|
|
|||
|
![Пример кода](https://raw.githubusercontent.com/sosmaniac-FCC/designatedata/master/image3_.png)
|
|||
|
|
|||
|
Обратите внимание на переход члена родительского `value` элемент `property` дочернего элемента. Это было бы невозможно, если у `property` не было декоратора @Input. От этого зависит Угловой компилятор.
|
|||
|
|
|||
|
Другой пример для @Output показывает, как событие перемещается от дочернего к родительскому. Имейте в виду, что @Output почти всегда относится к настраиваемым привязкам событий.
|
|||
|
|
|||
|
![Пример кода](https://raw.githubusercontent.com/sosmaniac-FCC/designatedata/master/image1.png)
|
|||
|
|
|||
|
Убедитесь , что вы импортировать `EventEmitter` , `@Input` и `@Output` от `@angular/common` , если вы собираетесь повторить любой из этих примеров.
|
|||
|
|
|||
|
#### Вывод
|
|||
|
|
|||
|
Это прекрасное место для остановки. Связывание данных охватывает широкий спектр вариантов использования. Эта тема стоит изучить далее на [веб-сайте Angular](https://angular.io) . Это не единственные способы управления данными в Angular. См. Ссылки в разделе Ресурсы для получения дополнительной информации.
|
|||
|
|
|||
|
### источники
|
|||
|
|
|||
|
1. [Угловая команда. Введение в компоненты. Google. Доступ к 26 мая 2018 года](https://angular.io/guide/architecture-components#data-binding)
|
|||
|
|
|||
|
### Ресурсы
|
|||
|
|
|||
|
* [Угловая документация](https://angular.io/docs)
|
|||
|
|
|||
|
* [Угловой репозиторий GitHub](https://github.com/angular/angular)
|
|||
|
|
|||
|
* [Подробнее о компонентах и шаблонах в угловом](https://angular.io/guide/displaying-data)
|