Angular对表单的处理

模板驱动表单

初始模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div class="container">
<h1>Hero Form</h1>
<form>
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" required>
</div>
<div class="form-group">
<label for="alterEgo">Alter Ego</label>
<input type="text" class="form-control" id="alterEgo">
</div>
<button type="submit" class="btn btn-success">Submit</button>
</form>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { Component } from '@angular/core';
import { Hero } from './hero';
@Component({
selector: 'app-hero-form',
templateUrl: './hero-form.component.html'
})
export class HeroFormComponent {
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; }
// TODO: Remove this when we're done
get diagnostic() { return JSON.stringify(this.model); }
}

引入FormsModule

1
2
3
4
5
6
7
8
import { FormsModule } from '@angular/forms';
@NgModule({
imports: {
FormsModule
}
})
export class AppModule { }
  • 应用就能访问模板驱动表单的所有特性,包括ngModel。

ngModel进行数据双向绑定

何为数据双向绑定: 数据从输入框流动到模型,再反向流动回来。

1
2
3
4
<input type="text" class="form-control" id="name"
required
[(ngModel)]="model.name" name="name">
TODO: remove this: {{model.name}}

  • [(ngModel)]=”model.name”,将input中的值与组件中的model.name进行双向绑定,获得更多的控制权,用于表单验证。
  • 在表单中使用[(ngModel)]时,必须要定义name属性,angular用它来注册组件。
  • name可以为任意唯一值,但取具有描述性的更好

声明模板变量

1
<form #heroForm="ngForm"></form>

  • Angular会在
    标签上自动创建并附加一个NgForm指令。
  • 它会控制那些带有ngModel指令和name属性的元素,监听他们的属性(包括其有效性)。 它还有自己的valid属性,这个属性只有在它包含的每个控件都有效时才是真。

表单校验

input元素的class类
是否访问过: ng-touched ng-untouchde
值是否变化: ng-dirty ng-pristine
值是否有效: ng-valid ng-invalid

CSS样式

新建样式文件,src/assets/forms.css

1
2
3
4
5
6
7
.ng-valid[required], .ng-valid.required {
border-left: 5px solid #42A948; /* green */
}
.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* red */
}

在index.html中的引入

1
<link rel="stylesheet" href="assets/forms.css">

隐藏和显示校验信息

1
2
3
4
5
6
7
8
9
<label for="name">Name</label>
<input type="text" class="form-control" id="name"
required
[(ngModel)]="model.name" name="name"
#name="ngModel">
<div [hidden]="name.valid || name.pristine"
class="alert alert-danger">
Name is required
</div>
  • 添加 #name=”ngModel”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{{ diagnostic}}
<div class="container" [hidden]="submitted">
<h1>Hero Form</h1>
<form (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 #name="ngModel" /> TODO: remove this: {{spy.className}}
<div [hidden]="name.valid || name.pristine" 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 power of powers" [value]="power">{{ power }}</option>
</select>
</div>
<button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button>
<button type="button" class="btn btn-default" (click)="newHero(); heroForm.reset()">New Hero</button>
<button type="submit" class="btn btn-success" [disabled]="!heroForm.form.valid">Submit</button>
</form>
</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-primary" (click)="submitted=false">Edit</button>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import { Component, OnInit } from '@angular/core';
import { Hero } from '../hero'
@Component({
selector: 'app-hero-form',
templateUrl: './hero-form.component.html',
styleUrls: ['./hero-form.component.css']
})
export class HeroFormComponent implements OnInit {
powers = ['Really Smart', 'Super Flexible',
'Super Hot', 'Weather Changer'];
model = new Hero(18, 'Dr IQ', this.powers[0], 'Chunck OverStreet')
submitted = false
onSubmit() {
this.submitted = true
}
newHero() {
this.model = new Hero(42, '', '')
}
constructor() { }
ngOnInit() {
}
get diagnostic() { return JSON.stringify(this.model) }
}