关于Angular中的数据绑定

在阅读 揭秘Angular2 书中第5.1.1和5.1.2章内容,觉得把整个架构中的数据流动讲得非常清楚,于是简单的记录一下

单向数据流动

文中提到了三种单向数据流动,分别是属性绑定、事件绑定、插值。
属性绑定和事件绑定既可以用于父子组件的数据传递,也可以用于组件数据模型和模板视图之间的数据传递。

在父子组件通信的过程中,模板充当类似于桥梁的角色,连接着二者的功能逻辑。
插值是一种单向的数据流动——从数据模型到模板视图。

父子组件通信过程

父到子:如果子组件需要父组件的参数值的时候,

父组件只需要组件类中有这个参数,然后在模板中,将其赋给一个属性

1
[toSonMessage]="toSonMessage"

然后子组件在组件类中@Input()这个属性,就可以获取啦~

1
@Input() toSonMessage;

子到父:也就是父组建中需要子组件的参数值,

子组件中需要@Output()一个事件名称

1
@Output() toFatherMessage1 = new EventEmitter<any>();

并且在模板中触发一个函数

1
(keyup)="toTellFather()

然后在子组建类中编写这个函数,在其中触发要output的事件,将要传递的变量放在参数中

1
2
3
toTellFather(){
this.toFatherMessage1.emit(this.toFatherMessage);
}

就好像主动向上冒泡一样

而父组件模板中监听到了这个信号

1
(toFatherMessage1)="getFatherMessage($event)

并绑定一个函数,在模板类中编写这个函数,取得传递过来的参数。

1
2
3
getFatherMessage(param){
this.toFatherMessage = param;
}

data-bind

demo

1
2
3
4
5
6
7
8
9
// father.component.html
<h1>father</h1>
<form #father="ngForm">
<span>something you want to tell son component:</span>
<input type="text" [(ngModel)]="toSonMessage" name="toSonMessage">
</form>
<p>something son component to tell you:</p>
<span>{{toFatherMessage}}</span>
<app-son [toSonMessage]="toSonMessage" (toFatherMessage1)="getFatherMessage($event)"></app-son>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// father.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-father',
templateUrl: './father.component.html',
styleUrls: []
})
export class FatherComponent implements OnInit {

toSonMessage = '';
toFatherMessage = '';

constructor() { }

getFatherMessage(param){
this.toFatherMessage = param;
}

ngOnInit() {
}

}
1
2
3
4
5
6
7
8
// son.component.html
<h2>son</h2>
<form #son="ngForm">
<span>something you want to tell father component:</span>
<input type="text" [(ngModel)]="toFatherMessage" name="toFatherMessage" (keyup)="toTellFather()">
</form>
<p>something father component to tell you:</p>
<span>{{toSonMessage}}</span>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// son.component.ts
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
selector: 'app-son',
templateUrl: './son.component.html',
styleUrls: []
})
export class SonComponent implements OnInit {

toFatherMessage = '';

@Input() toSonMessage;
@Output() toFatherMessage1 = new EventEmitter<any>();

constructor() { }

toTellFather(){
this.toFatherMessage1.emit(this.toFatherMessage);
}

ngOnInit() {
}

}
  • 注意要在app.module.ts中引入FormsModule
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { FatherComponent } from './father/father.component';
import { SonComponent } from './father/son/son.component';

@NgModule({
declarations: [
AppComponent,
FatherComponent,
SonComponent
],
imports: [
FormsModule,
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Angular变化监测机制

Angular是一个响应式系统,每次数据变动几乎都能实时处理,并更新对应视图。那么Angular是如何感知数据对象发生了变动呢?

Angular是以适当的时机去检验对象的值是否被改动,这个适当的时机指的是通常在用户操作事件(如单机),setTimeout或XHR回调等这些异步事件触发之后。Angular捕获这些异步事件的工作是通过Zones库实现的。

如图所示,每个组件背后都维护着一个独立的变化监测器,每个应用以组件树的形式组织,因此每个应用也有着对应的一颗变化监测树。当Zone捕获到某异步事件后,它都会通知Angular执行变化监测操作,每次变化监测操作都始于根组件,并以深度优先的原则向叶子组件遍历执行。

如果想要手动捕获变化事件做一些额外处理,Angular还提供了完善的生命周期钩子给开发者调用,如ngOnChanges,ngOnDestroy等等。

等多内容就不在这一章节中进行剖析了。

双向数据绑定

插值: ——单向数据绑定,从数据模型到模板视图。

双向数据绑定: [(ngModel)]="toSonMessage" ,[()]是实现双向绑定的语法糖,ngModel是辅助实现双向绑定的内置指令。

管道

针对数据的格式化显示。格式化输出但不影响本身的值。

1
{{ contact.telephone | phone }}