Angular 相应式表单之表单分组

1、案例需求

表单提交,表单悉数校验胜利才提交,当表单校验毛病,表单边框变红,同时有毛病提醒信息,有重置功用

2、名词解释

在剖析代码之前,起首明白 FormControl、formControl、formControlName、FormGroup、formGroup、formGroupName、FormArray、formArray、formArrayName 都是什么意思以及它们的用法。

2.1、FormControl

  • FormControl:跟踪自力表单控件的值和考证状况。它和 FormGroup 和 FormArray 是 Angular 表单的三大基础组织块之一。它扩大了 AbstractControl 类,并完成了关于接见值、考证状况、用户交互和事宜的大部分基础功用。

当运用相应式表单时,FormControl 类是最基础的组织块。要注册单个的表单控件,在组件中导入 FormControl 类,并建立一个 FormControl 的新实例,把它保存在类的某个属性中。

export class AppComponent implements OnInit {
    const control = new FormControl('', Validators.required);
    console.log(control.value);      // ''
    console.log(control.status);     // 'INVALID'
}

在组件类中建立了控件以后,还要把它和模板中的一个表单控件关联起来,为表单控件增加 formControl 绑定。

<label>
  Name:
  <input type="text" [formControl]="name">
</label>
  • formControl:是一个输入指令,接收 FormControl 的实例,在模版中运用。
  • formControlName: 也是输入指令,然则它接收的是一个字符串,同 formGroup 指令合营运用。
<div>
  <input type="text" [formControl]="myForm.controls.firstName"/>
  <input type="text" [formControl]="myForm.controls.lastName"/>
  <input type="text" [formControl]="myForm.controls.email"/>
  <input type="text" [formControl]="myForm.controls.title"/>
</div>

//等同于

<div [formGroup]="myForm">
  <input type="text" formControlName="firstName"/>
  <input type="text" formControlName="lastName"/>
  <input type="text" formControlName="email"/>
  <input type="text" formControlName="title"/>
</div>

2.2、FormGroup

  • FormGroup:跟踪一组 FormControl 实例的值和有效性状况

FormGroup 把每一个子 FormControl 的值聚合进一个对象,它的 key 是每一个控件的名字。它经由过程归集其子控件的状况值来计算出本身的状况。假如组中的任何一个控件是无效的,那末全部组就是无效的。

2.3、FormArray

  • FormArray:跟踪一个控件数组的值和有效性状况

FormArray 聚合了数组中每一个表单控件的值。它会依据其所有子控件的状况总结出本身的状况。假如 FromArray 中的任何一个控件是无效的,那末全部数组也会变成无效的。

  • FormControl、FormGroup、FormArray 类 用法一致
  • formControl、formGroup、formArray 输入指令 值为对应类的实例 用法一致
  • formControlName、formGroupName、formArrayName 输入指令 值为字符串 用法一向

3、代码剖析

fromGroup 能够然我们对表单内容举行分组,轻易我们在语义上辨别差别范例的输入,本例中,地点细分为“省”、“市”、“区”。

this.formGroup = this.fb.group({
      name: ['', nameValidator()],
      age: ['', ageValidator()],
      sex: ['', sexValidator()],
      address: this.fb.group({
        province: ['', requiredValidator('请输入省')],
        city: ['', requiredValidator('请输入市')],
        district: ['', requiredValidator('请输入区')]
      })
    });

address 此时不是 fromControl 而是 formGroup。

<div class="form-group"
    formGroupName="address">
    <label>地点:</label>
    <div>
      <label>省:</label>
      <input type="text"
        formControlName="province">
      <p>{{errorMessage('province')}}</p>
    </div>
    <div>
      <label>市:</label>
      <input type="text"
        formControlName="city">
      <p>{{errorMessage('city')}}</p>
    </div>
    <div>
      <label>区:</label>
      <input type="text"
        formControlName="district">
      <p>{{errorMessage('district')}}</p>
    </div>
  </div>

在猎取 省市区的 formControl 时,能够经由过程如许猎取

// 太庞杂了
this.formGroup.controls['address'].controls['province'];

// 一样庞杂
this.formGroup.get('address').controls['province'];

// 还好
this.formGroup.get(['address', 'province']);

第三种体式格局虽然简朴,然则不够圆满,get要领不能一步到位,必需同时传入 formGroupName 和 formControlName。因此在检察单个表单是不是有毛病信息时,必需先推断 formControlName 是子组件照样孙子组件。

errorMessage(formControlName: string): string {

    let control: AbstractControl;

    if (this.formGroup.contains(formControlName)) {
      control = this.formGroup.get(formControlName);
    } else {
      control = this.formGroup.get(['address', formControlName]);
    }
    return ((control.touched || control.dirty) && control.invalid) ? control.errors.message : '';
  }

contains要领:检查组内是不是有一个具有指定名字的已启用的控件,存在返回 true,不存在返回 false。

    原文作者:whyneedname
    原文地址: https://segmentfault.com/a/1190000018249859
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞