使用插值表达式将一个表达式的值显示在模板上
<h1>{{productTitle}}</h1>
<img [src]="imgUrl">
使用小括号将组件控制器的一个方法绑定为模板上一个事件的处理器
<button (click)="toProductDetail()">商品详情</button>
默认的绑定是单向的
事件绑定
如果处理事件的方法需要了解事件的属性可以给处理事件的方法添加一个$event参数
这个参数的target属性指向触发事件的DOM对象,也就是input节点。
新建一个项目ng new demo1
新建一个组件ng g component bind
修改bind.component.html
<p>
bind works!
</p>
<button (click)="doOnClick($event)">点我</button>
修改bind.component.ts
export class BindComponent implements OnInit {
constructor() { }
ngOnInit() {
}
doOnClick(event:any){
console.log(event);
}
}
修改app.component.html
<app-bind></app-bind>
启动程序
DOM属性编程
修改bind.component.html
<p>
bind works!
</p>
<img [src]="imgUrl">
<img src="{{imgUrl}}">
修改bind.component.ts
export class BindComponent implements OnInit {
imgUrl:string="http://placehold.it/400x220";
constructor() { }
ngOnInit() {
}
}
实际上,Angular渲染页面前会把插值表达式翻译成属性绑定
插值表达式和属性绑定是一个东西。没有哪个更好一说,但编程的时候尽量用一种写法。
修改bind.component.html
<p>
bind works!
</p>
<input value="Tom" (input)="doOnInput($event)">
修改bind.component.ts
export class BindComponent implements OnInit {
constructor() { }
ngOnInit() {}
doOnInput(event:any){
console.log(event.target.value);//dom属性值,会改变
console.log(event.target.getAttribute('value'));//html属性,初始值,不会改变
}
}
会发现HTML属性打印的始终是Tom,而dom属性会随着输入内容的改变而改变。
- 少量HTML属性和DOM属性之间有着1对1的映射,如id
- 有些HTML属性没有对应的DOM属性,如colspan
- 有些DOM属性没有对应的HTML属性,如textContent
- 就算名字相同,HTML属性和DOM属性也不是同一样东西
- HTML属性的值指定了初始值;DOM属性的值表示当前值
- DOM属性的值可以改变;HTML属性的值不能改变
- 模板绑定是通过DOM属性和事件来工作的,而不是HTML属性
插值表达式是DOM属性绑定
HTML属性绑定
基本HTML属性绑定
<td [attr.colspan]="tableColspan">Something<td>
我们应该优先使用DOM属性绑定,那么为什么还要用HTML属性绑定呢。当没有DOM属性绑定的时候就要用HTML属性绑定了。
比如td的colspan是纯HTML属性,没有对应的DOM属性
修改bind.component.html
<p> bind works! </p> <table> <tr><td colspan="{{1+1}}">慕课网</td> </tr> </table>
查看控制台,会发现会报一个异常
Uncaught Error: Template parse errors: Can't bind to 'colspan' since it isn't a known property of 'td'. (" </p> <table> <tr><td [ERROR ->]colspan="{{1+1}}">慕课网</td> </tr> </table>
因为插值表达式是DOM属性绑定只能去设置td的DOM属性,不能设置其HTML属性。
在这种情况下只能使用HTML属性绑定。
修改bind.component.html
<p>
bind works!
</p>
<table>
<tr><td [attr.colspan]="size">慕课网</td> </tr>
</table>
size:number=2;
CSS属性绑定
CSS类绑定
<div class="aaa bbb" [class]="someExpression">something</div> <div [class.special]="isSpecial">something</div> <div [ngClass]="{{aaa:isA,bbb:isB}}">
第一种[class]的样式会代替前边class的样式
第二种,isSpecial是一个布尔值,为true则显示这个样式
第三种,可以控制多个class是否显示,aaa就是class类的名字
样式绑定
<button [style.color]="isSpecial?'red':'green'">Red</button> <div [ngStyle]="{'font-style':this.canSave?'italic':'normal'}">
CSS类绑定
修改bind.component.css
.a{ background: yellow; }
.b{ color:red; }
.c{ font-size:60px; }
修改bind.component.html
<p>
bind works!
</p>
<div class="a b c">慕课网</div>
然后查看页面。
这是用原始的方式来绑定class类。
修改bind.component.html
<p>
bind works!
</p>
<div [class]="divClass">慕课网</div>
修改bind.component.ts,设置3秒后改变class属性
divClass:string;
constructor() { setTimeout(()=>{ this.divClass="a b c" },3000) }
第二种绑定方式,只改变部分class
修改bind.component.html
<p>
bind works!
</p>
<div class="a b" [class.c]="isBig">慕课网</div>
修改bind.component.ts
isBig:boolean=false;
constructor() { setTimeout(()=>{ this.isBig=true; },3000) }
同时管理多个类
修改bind.component.html
<p>
bind works!
</p>
<div [ngClass]="divClass">慕课网</div>
修改bind.component.ts
divClass: any = { a: false,b: false,c: false }
constructor() { setTimeout(() => { this.divClass = { a: true,b: true,c: true } },3000) }
内联class的绑定
<p>
bind works!
</p>
<div [style.color]="isDev?'red':'blue'">慕课网</div>
isDev:boolean=true;
constructor() { setTimeout(() => { this.isDev=false; },3000) }
设置多个内联样式
<p>
bind works!
</p>
<div [ngStyle]="divStyle">慕课网</div>
divStyle:any={ color:'red',background:'yellow' }
constructor() { setTimeout(() => { this.divStyle={ color:'yellow',background:'red' } },3000) }
双向绑定
以前学的都是单向绑定,比如事件是从模板到控制器
属性绑定是从控制器到模板
<p>
bind works!
</p>
<input (input)="doOnInput($event)">
<input [value]="name">
name:string;
doOnInput(event) {
}
但有时候我们想让这两种绑定同时生效
<p>
bind works!
</p>
<input [value]="name" (input)="doOnInput($event)">
{{name}}
export class BindComponent implements OnInit {
name:string;
constructor() {
setInterval(()=>{ //从控制器到模板
this.name="Tom";
},3000)
}
ngOnInit() {
}
doOnInput(event) {
this.name=event.target.value;//从模板到控制器
}
}
启动项目
我修改文本框中内容name会改变。同时每隔3秒会把页面中的内容改为Tom。
这就实现了双向绑定,但这样既要写属性又要写事件。很麻烦。
Angular提供了ngModule指令来简化写法。
修改bind.component.html
<p>
bind works!
</p>
<input [(ngModel)]="name">
{{name}}
这样也会实现前面的那种效果。
报了个错误
Can't bind to 'ngModel' since it isn't a known property of 'input'. ("
解决方案,在app.module.ts中加上FormsModule
import{FormsModule} from '@angular/forms'
imports: [
BrowserModule,FormsModule
],