2.3 双向数据绑定
接下来的问题是我们是否只能通过这种方式进行表现层和逻辑之间的数据交换呢?如果我们希望在组件内对数据进行操作后再反馈到界面应该怎么处理呢?Angular 2提供了一个双向数据绑定的机制。这个机制是这样的,在组件中提供成员数据变量,然后在模板中引用这个数据变量。我们来改造一下login.component.ts,首先在class中声明两个数据变量username和password:
username = "";
password = "";
然后去掉onClick方法的参数,并将内部的语句改造成如下样子:
console.log('auth result is: '
+ this.service.loginWithCredentials(this.username, this.password));
去掉参数的原因是双向绑定后,我们通过数据成员变量就可以知道用户名和密码了,不需要再传递参数了。而成员变量的引用方式是this.成员变量。 然后我们来改造模板:
<div>
<input type="text"
[(ngModel)]="username"
/>
<input type="password"
[(ngModel)]="password"
/>
<button (click)="onClick()">Login</button>
</div>
[(ngModel)]=”username”这个看起来很别扭,稍微解释一下,方括号[]的作用是说把等号后面当成表达式来解析而不是当成字符串,如果我们去掉方括号那就等于说是直接给这个ngModel赋值成“username”这个字符串了。方括号的含义是单向绑定,就是说我们在组件中给model赋的值会设置到HTML的input控件中。
[()]是双向绑定的意思,就是说HTML对应控件的状态改变会反射设置到组件的model中。ngModel是FormModule中提供的指令,它负责从Domain Model(这里就是username或password,以后我们可以绑定更复杂的对象)中创建一个FormControl的实例,并将这个实例和表单的控件绑定起来。
同样,对于click事件的处理,我们不需要传入参数了,因为其调用的是刚刚我们改造的组件中的onClick方法。现在我们保存文件后打开浏览器看一下,效果和上一节的应该一样。本节的完整代码如下:
//login.component.ts
import { Component, OnInit, Inject } from '@angular/core';
@Component({
selector: 'app-login',
template: '
<div>
<input type="text"
[(ngModel)]="username"
/>
<input type="password"
[(ngModel)]="password"
/>
<button (click)="onClick()">Login</button>
</div>
',
styles: []
})
export class LoginComponent implements OnInit {
username = '';
password = '';
constructor(@Inject('auth') private service) {
}
ngOnInit() {
}
onClick() {
console.log('auth result is: '
+ this.service.loginWithCredentials(this.username, this.password));
}
}