跳到主要内容

模板式表单,响应式表单2

一、模板式表单

模板式表单常用于form表单,用于注册登录等表单提交。

模板式表单需要引入模板式表单模块,这个模块在项目创建时会自动引入。

imports: [
FormsModule,
],

创建一个login组件进行示例:

<form>
<div>用户名:<input type="text"></div>
<div>密码:<input type="text"></div>
<input type="submit" value="登录">
</form>

1、只要创建了form表单,就会自动被FormsModule模块接管。

2、如果创建的不是form表单(比如div),如果想让这个div被模板式表单接管,需要指令 ngForm 将标签标识为模板式表单。

<div ngForm>
<div>用户名:<input type="text"></div>
<div>密码:<input type="text"></div>
<input type="submit" value="登录">
</div>

form表单自带的submit也会被angular的ngSubmit事件接管。

<form (ngSubmit)="getData()">
<div>用户名:<input type="text"></div>
<div>密码:<input type="text"></div>
<input type="submit" value="登录">
</form>

如何获取表单的值?

  • 通过ngModel将各个input挂载到myForm(input必须有name属性)
  • form表单定义变量mgForm为ngForm,用来操作表单
  • ngSubmit触发函数getData的参数mgForm.value即是所有表单的值的集合,是一个对象。
<form (ngSubmit)="getData(mgForm.value)" #mgForm="ngForm">
<div>用户名:<input type="text" name="user" ngModel></div>
<div>密码:<input type="text" name="pwd" ngModel></div>
<input type="submit" value="登录">
</form>

由于定义的变量myForm只能在模板中被访问到,控制器想访问只能通过参数传递,所以叫模板式表单。

可以直接在页面显示form表单值的对象:

<form (ngSubmit)="getData(mgForm.value)" #mgForm="ngForm">
<div>用户名:<input type="text" name="user" ngModel></div>
<div>密码:<input type="text" name="pwd" ngModel></div>
<input type="submit" value="登录">
<!-- 直接显示 (json为内置管道)-->
{{myForm.value | json}}
</form>

也可以将表单中各个input的值进行分组:

使用ngModelGroup分组:

<form (ngSubmit)="getData(mgForm.value)" #mgForm="ngForm">
<div>用户名:<input type="text" name="user" ngModel></div>
<div ngModelGroup="pwdGroup">
<div>密码:<input type="text" name="pwd" ngModel></div>
<div>确认密码:<input type="text" name="pwd2" ngModel></div>
</div>
<input type="submit" value="登录">
</form>

未分组的时候:{user: "", pwd: "", pwd2: ""}

分组后:{user: "", pwdGroup: {pwd: "", pwd2: ""}}

二、继续响应式表单

之前只是简单的一个input标签,现在是一个表单集合,如何使用响应式表单进行数据的获取和提交。

响应式表单和模板式表单对比:

模板式表单很难做到在控制器中实时监听表单数据的变化,只能在提交的时候将数据传回给控制器,但是响应式表单可以做到实时监听表单数据的变化。

1、一个完整的响应式表单

1.1、在主模块引入ReactiveFormsModule响应式表单模块

1.2、在控制器定义表单数据模型:

loginForm: FormGroup = new FormGroup({
user: new FormControl('Daotin'),
pwdGroup: new FormGroup({
pwd: new FormControl(),
pwd2: new FormControl()
})
});

1.3、映射到视图

  • 表单数据模型loginForm映射到formGroup
  • 分组pwdGroup映射到formGroupName
  • 单个表单映射到formControlName
<form [formGroup]="loginForm">
<div>用户名:<input type="text" formControlName="user"></div>
<div formGroupName="pwdGroup">
<div>密码:<input type="text" formControlName="pwd"></div>
<div>确认密码:<input type="text" formControlName="pwd2"></div>
</div>
<input type="submit" value="登录">
</form>

1.4、点击提交获取表单数据

给表单添加submit事件:

<form [formGroup]="loginForm" (submit)="getData()">
<div>用户名:<input type="text" formControlName="user"></div>
<div formGroupName="pwdGroup">
<div>密码:<input type="text" formControlName="pwd"></div>
<div>确认密码:<input type="text" formControlName="pwd2"></div>
</div>
<input type="submit" value="登录">
</form>
getData() {
// 通过表单数据模型的value获取表单的数据
console.log(this.loginForm.value);
}

2、其他获取表单的值

获取表单中单个的值this.loginForm.get('user').value

监听表单中单个的值的变化this.loginForm.get('user').valueChanges.subscribe(value => {})

监听整个表单任意值的变化this.loginForm.valueChanges.subscribe(obj => { })

3、表单的个数不确定

现在有两个按钮,一个添加,一个删除,用来动态添加或删除邮箱表单。

由于邮箱的表单的个数不确定,所以会用到FromArray

3.1、定义emails数据模型

  loginForm: FormGroup = new FormGroup({
user: new FormControl('Daotin'),
pwdGroup: new FormGroup({
pwd: new FormControl(),
pwd2: new FormControl()
}),
// emails数据模型
emails: new FormArray([
new FormControl(),
])
});

3.2、绑定数据模型到视图

<div formArrayName="emails">
<div *ngFor="let item of loginForm.get('emails').controls; let i = index">
邮箱{{i+1}}:<input type="text" [formControlName]="i">
</div>
</div>
<button (click)="addEmail()">添加邮箱</button>
<button (click)="delEmail()">删除邮箱</button>

emails的数组通过loginForm.get('emails').controls 获取。

email表单formContril绑定的是索引index。

3.3、点击按钮添加删除邮箱

addEmail() {
// 由于只有FormArray有push方法(这个push不是数组中的push,而是由FormArray对象提供的方法),
// 所以 as FormArray 表示:声明返回值为FormArray类型
let emailsArray = this.loginForm.get('emails') as FormArray;
// 添加一个邮箱
emailsArray.push(new FormControl());
}
delEmail() {
let emailsArray = this.loginForm.get('emails') as FormArray;
// 移除最后一个邮箱
emailsArray.removeAt(emailsArray.length - 1);
}