首先写一个例子:
html:
<h1> {{title}} </h1> {{diagnostic}} <div [hidden]="submitted"> <div class="container"><h1>Hero Form</h1> <form *ngIf="active" (ngSubmit)="onSubmit()" #heroForm="ngForm"> <div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name" #spy> TODO: remove this:{{spy.className}} <div [hidden]="spy.value==null" class="alert alert-danger"> Name is required </div> </div> <div class="form-group"> <label for="alterEgo">Alter Ego</label> <input type="text" class="form-control" id="alterEgo" [(ngModel)]="model.alterEgo" name="alterEgo"> </div> <div class="form-group"> <label for="power">Hero Power</label> <select class="form-control" id="power" required [(ngModel)]="model.power" name="power"> <option *ngFor="let p of powers" [value]="p">{{p}}</option> </select> </div> <button type="submit" class="btn btn-default" [disabled]="!heroForm.form.valid" >Submit</button> <button type="button" class="btn btn-default" (click)="newHero1()">New Hero</button> </form> </div> </div> <div [hidden]="!submitted"> <h2>You submitted the following:</h2> <div class="row"> <div class="col-xs-3">Name</div> <div class="col-xs-9 pull-left">{{ model.name }}</div> </div> <div class="row"> <div class="col-xs-3">Alter Ego</div> <div class="col-xs-9 pull-left">{{ model.alterEgo }}</div> </div> <div class="row"> <div class="col-xs-3">Power</div> <div class="col-xs-9 pull-left">{{ model.power }}</div> </div> <br> <button class="btn btn-default" (click)="submitted=false">Edit</button> </div>
component:
import { Component } from '@angular/core'; import { Hero } from './hero'; @Component({ moduleId: module.id, selector: 'hero-form', templateUrl: 'hero.component.html' }) export class HeroComponent { powers = ['Really Smart', 'Super Flexible', 'Super Hot', 'Weather Changer']; model = new Hero(18, 'Dr IQ', this.powers[0], 'Chuck Overstreet'); submitted = false; onSubmit() { this.submitted = true; } get diagnostic() { return JSON.stringify(this.model); } active = true; newHero1() { console.log("进来了"); this.model = new Hero(42, '', ''); this.active = false; setTimeout(() => this.active = true, 0); } }何为数据的双向绑定,angular2的开发文档是这么介绍的:绑定语法中的[()]是一个很好的线索,在属性绑定中, 一个值从模型中传到屏幕上的目标属性。 我们通过把名字括在方括号中来标记出目标属性, []。 这是一个从模型到视图的单向数据绑定。
在事件绑定中, 值从屏幕上的目标属性传到模型中。 我们通过把名字括在圆括号中来标记出目标属性, ()。 这是一个从视图到模型的反向单向数据绑定。
不出所料, Angular选择了组合标点 [()] 来标记出双向数据绑定和双向数据流。
事实上, 我们可以把NgModel绑定拆成两个独立的绑定, 就像我们重写的“Name”<input>绑定一样:
<input type="text" class="form-control" id="name" required [ngModel]="model.name" name="name" (ngModelChange)="model.name = $event" >
这个属性绑定看起来很眼熟, 但事件绑定看起来有点怪。
ngModelChange并不是<input>元素的事件。 它实际上是一个来自ngModel指令的事件属性。 当Angular在表单中看到一个[(x)]的绑定目标时, 它会期待这 个x指令有一个名为x的输入属性, 和一个名为xChange的输出属性。
模板表达式中的另一个古怪之处是model.name = $event。 我们以前看到的$event变量是来自DOM事件的。 但ngModelChange属性不会生成DOM事件 —— 它是一个Angular EventEmitter类型的属性, 当它触发时, 它返回的是输入框的值 —— 它恰好和我们希望赋给模型上name属性的值一样。
很高兴知道这些, 但是这样现实吗? 实践上我们几乎总是优先使用[(ngModel)]形式的双向绑定。 只有当我们不得不在事件处理函数中做一些特别的事情(比 如合并或限制按键频率)时, 才需要拆分出独立的事件处理函数。