数据绑定总体而言有三种类型:
插值表达式绑定
既可以写在html结构中,也可以写在标签中
<p>My current hero is {{currentHero.name}}</p> <img src="{{heroImageUrl}}" style="height:30px">
属性绑定:[属性名]
// 元素属性设置为组件属性的值,image 元素的src属性会被绑定到组件的heroImageUrl属性上 <img [src]="heroImageUrl"> // 设定自定义组件的模型属性(这是父子组件之间通讯的重要途径) <app-hero-detail [hero]="currentHero"></app-hero-detail>
注意别忘了[],忘记了[],则相应属性就被绑定到了字符串上,而不是背后所代表的值。
有时候也可以通过插值表达式实现一样的效果
<img src="{{heroImageUrl}}">
Attribute绑定
当元素没有属性(native property)可绑的时候,就必须使用 attribute 绑定,例如<td>
元素没有colspan
属性,但是插值表达式和属性绑定只能设置属性,不能设置 attribute,这时我们便需要使用到attribute绑定来替我们解决这个问题。
如果对property和attribute有所疑惑,可通过下面的文字先做一个区分梳理:
attribute初始化DOM property,然后它们的任务就完成了,property的值可以改变;attribute 的值不能改变。
例如,当浏览器渲染<input type="text" value="abc">时,它将创建相应DOM 节点,其value property被初始化为“abc”。当用户在输入框中输入“abcwwww”时,DOM元素的value property变成了“abcwwww”。但是这个HTML value attribute保持不变。如果我们读input元素的attribute,就会发现确实没变:input.getAttribute('value') // 返回 "abc"。
所以,在Angular的世界中,attribute唯一的作用是用来初始化元素和指令的状态。 当进行数据绑定时,只是在与元素和指令的property和事件打交道,而attribute就基本上靠边站了,只有比较特殊的情况才会用到他。
具体绑定格式如下:
<tr><td [attr.colspan]="1 + 1">One-Two</td></tr>
Class绑定和Style绑定
借助 CSS 类绑定,可以从元素的class attribute 上添加和移除 CSS 类名。
// 替换型绑定:即当 badCurly 有值时class的值会被完全替换成一个badCurly. <div class="bad curly special" [class]="badCurly">Bad curly</div> // 增减类绑定:绑定到特定的类名 <div [class.special]="isSpecial">The class binding is special</div>
如果要同时替换多个class,使用ngClass指令绑定到一个对象上是更好的选择:通过修改currentClasses的值可以同时修改1/n个class.
<div [ngClass]="currentClasses">xxxx</div>
通过样式绑定,可以设置内联样式,样式属性命名方法可以用中线命名法,也可以用驼峰式命名法,如fontSize。
<button [style.background-color]="canSave ? 'cyan': 'grey'" >Save</button> // 单位也写在方括号里,这个很方便啊 <button [style.font-size.px]="isSpecial ? 30 : 12" >Big</button>
同样也可以通过ngStyle指令把内联样式绑定到一个对象上。
<div [ngStyle]="currentStyle">xxxx</div>
事件绑定:(事件名)
事件绑定分为对原生DOM事件绑定和自定义事件绑定。原生事件可以通过$event访问事件对象,它有像target和target.value这样的属性。
// 事件绑定监听按钮的点击事件。每当点击发生时,都会调用组件的onSave()方法。 <button (click)="onSave()">Save</button> // 当input值发生改变时,自动更新currentHero.name的值 <input (input)="currentHero.name=$event.target.value">
// (子)组件定义了deleteRequest属性,它是EventEmitter实例 deleteRequest = new EventEmitter<Hero>(); // 当触发delete事件时,指令调用EventEmitter.emit(payload)来触发事件 delete() { this.deleteRequest.emit(this.hero); } // (父)组件监听到了deleteRequest事件就调用deleteHero方法,并通过$event对象来访问载荷this.hero <app-hero-detail (deleteRequest)="deleteHero($event)"></app-hero-detail>
双向数据绑定: [(...)]
双向绑定实质上是属性绑定和事件绑定的语法糖。
// 在没有双向绑定之前可能需要这样写 <app-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></app-sizer> // 但有了双向绑定之后,只需要这样就行了 <app-sizer [(size)]="fontSizePx"></app-sizer>
父子组件之间可以通过EventEmitter来进行操作,原生html元素就需要依赖自身的值变化事件了,但即使可以操作这样写也不够优雅,所幸我们可以通过[(ngModel)]指令来完成。值得注意的是,这种指令也只是针对表单元素,对于组件还是需要使用前文提及的双向绑定语法。
还有一点是,表单元素使用过程会需要一些注意的地方,还请查看表单相关文档/稍后写的文章,下面代码仅作为语法示例。
<input [(ngModel)]="currentHero.name">
文章先写到这吧,还有一些其他的工具和数据绑定关系不算特别大就放在其他笔记中啦~~
前端新人,写的不对的地方还请指出;如果觉得对你有帮助,可以点个赞鼓励一下我哦!~~