这节将讲述表单的使用,我们使用表单时不在使用原始表单,而是使用Bootstrap集成到Angular中来使用
安装Bootstrap
npm install bootstrap --save
- 引用css样式,修改
.angular-cli.json
文件中的styles节点内容:
"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
"styles.css"
],
创建组件和相关类
ng generate component myform/MyForm1
ng generate class myform/MyUser
还是仍然修改app.module.ts和index.html
my-form1.component.html
<div class="container">
<div [hidden]="submitted">
<form (ngSubmit)="onSubmit()" #userForm="ngForm" role="form">
<legend>创建用户</legend>
<div class="form-group">
<label for="name">姓名</label>
<input type="text" class="form-control" id="name" placeholder="请输入姓名..." name="name" required [(ngModel)]="model.name" #name="ngModel">
<div [hidden]="name.valid || name.pristine"
class="alert alert-danger">
姓名必须
</div>
</div>
<div class="form-group">
<label for="age">年龄</label>
<!--这里我们创建了一个模板变量age-->
<input type="text" class="form-control" id="age" placeholder="请输入年龄..." name="age" required [(ngModel)]="model.age" #age="ngModel">
<div [hidden]="age.valid || age.pristine"
class="alert alert-danger">
年龄必须
</div>
</div>
<div class="form-group">
<label for="school">学校</label>
<input type="text" class="form-control" id="school" placeholder="请输入学校..." name="school" [(ngModel)]="model.school">
</div>
<div class="form-group">
<label for="hobby">爱好</label>
<select class="form-control" id="hobby" required [(ngModel)]="model.hobby" name="hobby" #hobby="ngModel">
<option value="">请选择</option>
<option *ngFor="let hob of hobbys" [value]="hob"></option>
</select>
<div [hidden]="hobby.valid || hobby.pristine" class="alert alert-danger">
爱好必须填写
</div>
</div>
<!--只有验证都通过了按钮才可用-->
<button type="submit" class="btn btn-success" [disabled]="!userForm.form.valid">保存</button>
<button type="button" class="btn btn-default" (click)="newUser(); userForm.reset()">重置表单</button>
</form>
</div>
<div [hidden]="!submitted">
<h2>提交内容:</h2>
<div class="row">
<div class="col-xs-3">姓名</div>
<div class="col-xs-9 pull-left"></div>
</div>
<div class="row">
<div class="col-xs-3">年龄</div>
<div class="col-xs-9 pull-left"></div>
</div>
<div class="row">
<div class="col-xs-3">学校</div>
<div class="col-xs-9 pull-left"></div>
</div>
<div class="row">
<div class="col-xs-3">爱好</div>
<div class="col-xs-9 pull-left"></div>
</div>
<br>
<button class="btn btn-primary" (click)="submitted=false">编辑</button>
</div>
</div>
上面用到了大量的数据绑定的东东,先一句一句的分析下吧
[hidden]="submitted"
单向值绑定(property hidden绑定到表达式submitted的结果),将数据源中submitted
property 绑定到视图的hidden的attribute(区分开这两个属性的意义),
property是dom级别的,attribute是HTML元素级别的,hidden在attribute中只要出现了,那么就会被隐藏,所以我们使用[]
这样代表我们操作property,从而可以最终去操作attribute的hidden,这个其实就是Angular2的内置属性指令,后面会说到这个
(ngSubmit)="onSubmit()"
时间绑定,时间绑定都是圆括号,ngSubmit是Angular内置的一个属性
#userForm="ngForm"
定义了模板引用变量#userForm,并初始化为 “ngForm”。现在userForm变量引用的是NgForm指令,它代表的是表单的整体。NgForm是一个内置指令
[(ngModel)]="model.name"
这句其实就是将input
表单进行双向绑定到model的name属性上面
#name="ngModel"
创建了名叫name的变量,并且赋值为 “ngModel”。
[hidden]="name.valid || name.pristine"
这个和上面的相似下面用表格特殊说明下valid和pristine以及touched
状态 | 为真时的 CSS 类 | 为假时的 CSS 类 |
---|---|---|
控件已经被访问过 | ng-touched |
ng-untouched |
控件值已经变化 | ng-dirty |
ng-pristine |
控件值是有效的 | ng-valid |
ng-invalid |
*ngFor="let hob of hobbys"
这个其实是一个for循环,注意这个星号一定要填写,它代表着特殊的含义,后面会说到
my-form1.component.ts
import { Component, OnInit } from '@angular/core';
import {MyUser} from '../my-user';
@Component({
moduleId: module.id,
selector: 'app-my-form1',
templateUrl: './my-form1.component.html',
styleUrls: ['./my-form1.component.css']
})
export class MyForm1Component implements OnInit {
hobbys = ['滑冰', '跑步', '爬山', '游泳', '唱歌', '跳舞', '听音乐', '读书', '踢足球', '打篮球', '其他'];
model = new MyUser(3, 'luamas', 28, '无以开口', this.hobbys[this.hobbys.length - 1]);
submitted = false;
onSubmit() { this.submitted = true; }
newUser() {
this.model = new MyUser(3, '', null, '', '');
}
constructor() {
}
ngOnInit() {
}
}
moduleId: module.id
,属性设置了基地址,用于从相对模块路径加载templateUrl和styleUrls
其他没什么可说的,都是之前说过的一些东西.
my-form1.component.css
.ng-valid[required], .ng-valid.required {
border-left: 5px solid #42A948; /* green */
}
.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* red */
}
这里为错误和正确元素增加样式
my-user.ts
export class MyUser {
constructor(
public id: number,
public name: string,
// 这里一般用生日来计算,这里就不搞那么麻烦了
public age: number,
public school: string,
// 爱好加了?代表不是必须填写,可以为空,这个是typescript语法
public hobby?: string
) { }
}
MyUser类,这里需要说下hobby?: string
这个问号代表是否可以为空