angular 模板驱动表单 vs 响应式表单
2021-02-26 本文已影响0人
云上笔记
前置工作: 组件所在的 module
中导入表单模块
import { FormsModule,ReactiveFormsModule } from '@angular/forms';
模板驱动表单
创建表单:
<!-- form.components.html -->
<!-- novalidate: 禁止表单执行原生校验 -->
<!-- autocomplete off: 禁止 input 框的历史提示 -->
<form #tempForm="ngForm" novalidate autocomplete="off">
<!-- 判断字段是否通过正则校验,并显示对应的样式 -->
<div [ngClass]="{
'danger': phone.invalid && (phone.dirty || phone.touched),
'success': phone.valid && (phone.dirty || phone.touched)
}">
<input type="text"
[(ngModel)]="phone"
name="phone"
#phone="ngModel"
pattern="0?(13|14|15|17|18|19)[0-9]{9}"
required>
<!-- 显示对应的错误提示 -->
<div *ngIf="phone.errors && (phone.dirty || phone.touched)">
<p *ngIf="phone.errors?.required">手机号为必填</p>
<p *ngIf="phone.errors?.pattern">请输入合法的手机号码</p>
</div>
</div>
<!-- 获取表单字段的输入状态 -->
<p>valid: {{ tempForm.form.controls.phone?.valid }}</p>
<p>dirty: {{ tempForm.form.controls.phone?.dirty }}</p>
<p>touched: {{ tempForm.form.controls.phone?.touched }}</p>
<!-- 提交按钮,判断表单是否通过正则 -->
<button class="btn-primary" type="button" [disabled]="tempForm.invalid">确定</button>
</form>
通过FormsModule
引入的指令之一称为NgForm
,该指令具有一个与<form>
元素匹配的选择器。因此,只需将FormsModule
导入到 组件所在的module
中,我们的模板表单就已经与NgForm
指令的实例相关联。ngForm
的这个实例是隐藏的,但是我们可以使用附加在form
元素上的本地模板变量来获取它
获取表单实例
// form.components.ts
@ViewChild('tempForm') form: any;
ngOnInit() {
console.log(this.form.valid);
}
响应式表单
创建响应式表单
// components
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
public teamForm: FormGroup;
constructor(public fb: FormBuilder) {
this.createForm();
}
// 创建表单
private createForm() {
this.teamForm = this.fb.group({
name: ['', Validators.required],
remark: ['', Validators.maxLength(30)],
key: ['', Validators.compose([Validators.minLength(32)])]
});
}
// html
<form [formGroup]="teamForm" novalidate>
<div class="input-item">
<label class="required">名称</label>
<input class="form-control"
formControlName="name"
maxlength="50"
placeholder="请输入团队名称"
[ngClass]="{'err': teamForm.controls.name?.touched && teamForm.controls.name?.errors}"
(keydown)="datas.err = ''">
</div>
<!-- 错误提示 -->
<div class="inputErrMsg iconfont icon-alert-triangle"
*ngIf="teamForm.controls.name?.touched && teamForm.controls.name?.errors">
<app-error-msg errs="{{ teamForm.controls.name?.errors | json }}" name="名称">
</app-error-msg>
</div>
</form>
总结
特点 | 响应式表单 | 模板驱动表单 |
---|---|---|
设置 model | formControl 实例中设置 | 通过 ngModel directive 设置 |
数据更新 | 同步 | 异步 |
自定义校验规则 | 在函数中定义 | 通过directive 定义,如maxLenght这些 |
测试 | 与变更检测周期无交互 | 需要了解变更检测过程 |
变异性 | 不可变(始终为FormControl实例返回新值) | 可变(属性总是修改为新值) |
可扩展性 | 使用低级API可扩展性更高 | 由于API抽象,使用时可扩展性较差 |