前言
NG的核心部分之一就是数据绑定。它们是内嵌在HTML里面的表达式,用来在HTML文档里产生动态内容。
举个例子:
在这个例子中,div是宿主HTML元素,[]是单向数据绑定的标识,ngClass是目标(有指令型和属性型),getClasses()是表达式(可以直接写在模板里也可以是组件中的函数)。一句话就是宿主元素的目标要绑定到表达式上去,绑定的方向可以是单向的也可以是双向的。
分类
1.方括号单向数据绑定。
[目标]="表达式",数据流动方向为组件->模板
2.字符串插值绑定。
{{表达式}},数据流动方向为组件->模板
3.圆括号单向数据绑定。
(目标) ="表达式",数据流动方向为模板->组件。通常用来处理事件。
4.双向绑定。
[(目标)] ="表达式"。数据流动方向为模板组件
使用
方括号单向数据绑定
绑定属性时需要分清属性(property)和特性(attribute)绑定,绑定样式时有四种可选操作
property绑定
property是存在于DOM里的,例如input元素的value属性。
为了防止表达式返回NUll,在表达式后面跟上一个?
每个元素的property可以参考文档
attribute绑定
attribute是存在于HTML元素里的,不是所有的HTML元素的property都和attribute相符,比如说colspan。NG提供了绑定attribute属性的解决办法。
{{model.getProduct(1)?.name || 'None'}}
类和样式绑定
可以直接绑定HTML元素的样式或者类,也可以使用NG提供的指令达到目标。
类绑定
有三种方式。
[class]="表达式"
把表达式的结果替代原来存在的class
[class]="getClasses(1)"
[class.myClass]="表达式"
根据表达式返回结果添加myClass这个类
[class.myClass]="model.getProduct(2).price < 50"
[ngClass]="map"
把map对象的值添加到class里去,支持三种返回值:字符串,数组,对象
//html
[ngClass]="map"
//ts
map= {
"text-xs-center bg-danger": product.name == "Kayak",
"bg-info": product.price < 50
}
样式绑定
同样三种方式。不过没有替换样式的写法。
[style.color]="表达式"
把表达式的结果设置成单个样式属性。
[style.font-size.em]="表达式"
把表达式的结果设置成指定的样式和单位值。
[ngStyle]="map"
把样式设置成map对象的值。
//ts
map= {
fontSize: "30px",
"margin.px": 100,
color: product.price > 50 ? "red" : "green"
}
字符串插值绑定
它被用于宿主元素的文本内容中。也是一种单向数据绑定,常常用于显示某个数据。
{{data||getData()}}
圆括号单向数据绑定(事件绑定)
事件绑定用于响应宿主元素发送的事件。是用户交互的核心。事件种类请参考文档
{{i + 1}}也可以直接传入一个Event对象到组件里去。
当需要传入HTML元素到组件时,可以借助模板引用变量
使用双向数据绑定
使用ngModel指令可以简化了双向绑定的语法。
其实NG中的双向绑定就是同时利用了两个方向上的单向绑定,拆开看其实就是:
< input class="form-control" [ngModel]="selectedProduct" (ngModelChange)="selectedProduct=$event.target.value" />
实现原理
NG不像angular1.x使用脏检查来更新数据,而是使用了zone.js库来监视数据的变更,当组件里的数据发生了改变,NG会渲染模板DOM。当DOM的事件被触发了,NG会改变组件里的数据。
总结
数据绑定已经成为了当今前端框架不可或缺的核心特性之一,它让前端人员不再频繁关注视图(html)和逻辑(js)间的同步,而是专心编写高质量/可维护/松耦合的代码。