Angular 提供了多种数据绑定方式。绑定类型可以分为三类,按数据流的方向分为:
-
从数据源到视图
-
从视图到数据源
-
双向:视图到数据源到视图
绑定类型 | 语法 | 分类 |
---|---|---|
插值 | | 单向 |
事件 | | 从视图到数据源的单向绑定 |
双向 | | 双向 |
数据绑定
数据绑定使用 DOM 元素、组件和指令的 Property,而不是 HTML 的Attribute。
HTML attribute 与 DOM property 的对比
理解 HTML 属性和 DOM 属性之间的区别,是了解 Angular 绑定如何工作的关键。Attribute 是由 HTML 定义的。Property 是从 DOM(文档对象模型)节点访问的。
一些 HTML Attribute 可以 1:1 映射到 Property;例如,“ id”。
某些 HTML Attribute 没有相应的 Property。例如,
aria-*
。某些 DOM Property 没有相应的 Attribute。例如,
textContent
。重要的是要记住,HTML Attribute 和 DOM Property 是不同的,就算它们具有相同的名称也是如此。 在 Angular 中,HTML Attribute 的唯一作用是初始化元素和指令的状态。
模板绑定使用的是 Property 和事件,而不是 Attribute。
编写数据绑定时,你只是在和目标对象的 DOM Property 和事件打交道。
绑定类型与绑定目标
数据绑定的目标是 DOM 中的对象。 根据绑定类型,该目标可以是 Property 名(元素、组件或指令的)、事件名(元素、组件或指令的),有时是 Attribute 名。下表中总结了不同绑定类型的目标。
绑定类型 | 目标 | 范例 |
---|---|---|
属性 | 元素的 property |
|
事件 | 元素的事件 |
|
双向 | 事件与 property |
|
Attribute | attribute(例外情况) |
|
CSS 类 |
|
|
样式 |
|
|
事件绑定(event)
事件绑定允许你监听某些事件,比如按键、鼠标移动、点击和触屏。
在事件绑定中,angular会为目标事件设置事件处理器。当事件发生时,这个处理器会执行模板语句。 典型的模板语句通常涉及到响应事件执行动作的接收器,例如从 HTML 控件中取得值,并存入模型。
绑定会通过名叫 $event
的事件对象传递关于此事件的信息(包括数据值)。
事件对象的形态取决于目标事件。如果目标事件是原生 DOM 元素事件, $event
就是 DOM 事件对象,它有像 target
和 target.value
这样的属性。
<input [value]="currentItem.name" (input)="currentItem.name=$event.target.value" > without NgModel
上面的代码在把输入框的
value
属性绑定到name
属性。 要监听对值的修改,代码绑定到输入框的input
事件。 当用户造成更改时,input
事件被触发,并在包含了 DOM 事件对象 ($event
) 的上下文中执行这条语句。要更新
name
属性,就要通过路径$event.target.value
来获取更改后的值。
使用 EventEmitter
实现自定义事件
通常,指令使用 Angular EventEmitter 来触发自定义事件。 指令创建一个
EventEmitter
实例,并且把它作为属性暴露出来。 指令调用EventEmitter.emit(payload)
来触发事件,可以传入任何东西作为消息载荷。 父指令通过绑定到这个属性来监听事件,并通过$event
对象来访问载荷。
双向绑定的基础知识
- 设置特定的元素属性
- 监听元素的变更事件
[()]
语法很容易想明白:该元素具有名为 x
的可设置属性和名为 xChange
的相应事件。双向绑定语法实际上是属性绑定和事件绑定的语法糖。但是,没有哪个原生 HTML 元素会遵循 x
值和 xChange
事件的命名模式。
看例子:
双向绑定:[(ngModel)]
<label for="example-ngModel">[(ngModel)]:</label> <input [(ngModel)]="currentItem.name" id="example-ngModel">
通过分别绑定到
<input>
元素的value
属性和input
事件,可以达到同样的效果:<label for="without">without NgModel:</label> <input [value]="currentItem.name" (input)="currentItem.name=$event.target.value" id="without">
为了简化语法,
ngModel
指令把技术细节隐藏在其输入属性ngModel
和输出属性ngModelChange
的后面:<label for="example-change">(ngModelChange)="...name=$event":</label> <input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name=$event" id="example-change">
ngModel
输入属性会设置该元素的值,并通过ngModelChange
的输出属性来监听元素值的变化。