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抽象,使用时可扩展性较差
上一篇 下一篇

猜你喜欢

热点阅读