当前位置: 首页 > 工具软件 > FormBuilder > 使用案例 >

Angular2响应式表单FormGroup、FormArray、FormBuilder学习记录

明正德
2023-12-01

Angular2响应式表单FormGroup和FormArray学习记录

       响应式表单提供了一种模型驱动的方式来处理表单输入,其中的值会随时间而变化,从理解上来看应该是重脚本而轻模板。 FormControl,FormGroup,FormArray都适用于创建响应式表单,可以用他们统一管理form表单的状态和值。

响应式表单简介

响应式表单使用显式的、不可变的方式,管理表单在特定的时间点上的状态。对表单状态的每一次变更都会返回一个新的状态,这样可以在变化时维护模型的整体性。响应式表单是围绕 Observable 的流构建的,表单的输入和值都是通过这些输入值组成的流来提供的,它可以同步访问。

响应式表单还提供了一种更直观的测试路径,因为在请求时你可以确信这些数据是一致的、可预料的。这个流的任何一个消费者都可以安全地操纵这些数据。

响应式表单与模板驱动的表单有着显著的不同点。响应式表单通过对数据模型的同步访问提供了更多的可预测性,使用 Observable 的操作符提供了不可变性,并且通过 Observable 流提供了变化追踪功能。

FormControl、FormGroup、FormArray的依赖

       他们三个都是由ReactiveFormsModule模块提供,使用前需要在相应的模块中引入依赖。

import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [
    // other imports ...
    ReactiveFormsModule
  ],
})
export class AppModule { }

FormControl,FormGroup,FormArray的应用场景

       FormControl用于创建单个的元素控件实例,对单个控件进行赋值,取值,添加同步或异步校验,详细参见 Angular文档FormControl

import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'app-name-editor',
  templateUrl: './name-editor.component.html',
  styleUrls: ['./name-editor.component.css']
})
export class NameEditorComponent {
  name = new FormControl('');
    // 为控件赋值
  updateName() {
     this.name.setValue('Nancy');
  }
}
<label>
  Name:
  <input type="text" [formControl]="name">
</label>
<p>
  Value: {{ name.value }}
</p>

       FormGroup用于创建一组的元素控件,并可以对这一组控件进行整体的赋值,取值,验证等操作,还可以通过嵌套组件的方式构建层级结构的控件组,对于使用FormGroup嵌套需要用到FormGroupName指令,其内部依赖于FormControl;详细参见Angular文档 FormGroup

    有两种更新模型值的方式:

  • 使用 setValue() 方法来为单个控件设置新值。 setValue() 方法会严格遵循表单组的结构,并整体性替换控件的值。

  • 使用 patchValue() 方法可以用对象中所定义的任何属性为表单模型进行替换。

  setValue() 方法的严格检查可以帮助你捕获复杂表单嵌套中的错误,而 patchValue() 在遇到那些错误时可能会默默的失败。

import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';

@Component({
  selector: 'app-profile-editor',
  templateUrl: './profile-editor.component.html',
  styleUrls: ['./profile-editor.component.css']
})
export class ProfileEditorComponent {
  profileForm = new FormGroup({
    firstName: new FormControl(''),
    lastName: new FormControl(''),
    // 创建嵌套分组组件
    address: new FormGroup({
      street: new FormControl(''),
      city: new FormControl(''),
      state: new FormControl(''),
      zip: new FormControl('')
    })
  });
  updateProfile() {
    this.profileForm.patchValue({
      firstName: 'Nancy',
      address: {
        street: '123 Drew Street'
      }
    });
  }
  onSubmit() {
    console.warn(this.profileForm.value);
  }
}
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
  
  <label>
    First Name:
    <input type="text" formControlName="firstName">
  </label>

  <label>
    Last Name:
    <input type="text" formControlName="lastName">
  </label>
   <!-- 嵌套分组组件的应用 -->
  <div formGroupName="address">
    <h3>Address</h3>

    <label>
      Street:
      <input type="text" formControlName="street">
    </label>

    <label>
      City:
      <input type="text" formControlName="city">
    </label>
  
    <label>
      State:
      <input type="text" formControlName="state">
    </label>

    <label>
      Zip Code:
      <input type="text" formControlName="zip">
    </label>
  </div>
  <p>
    <button (click)="updateProfile()">Update Profile</button>
  </p>
  <button type="submit" [disabled]="!profileForm.valid">Submit</button>
</form>

        FormBuilder提供一种相对简单的方式用来创建FormControl和FormGroup以及FormArray;详细参见Angular文档 FormBuilder

       手动创建多个表单控件实例会非常繁琐。FormBuilder 服务提供了一些便捷方法来生成表单控件。FormBuilder 在幕后也使用同样的方式来创建和返回这些实例,只是用起来更简单。

FormBuilder 服务有三个方法:control()group()array()。这些方法都是工厂方法,用于在组件类中分别生成 FormControlFormGroupFormArray

       通过使用FormBuilder可以将上面的 FormGroup方式创建的组件简化成下方的样式,以此减少一些重复代码;

import { Component } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Validators } from '@angular/forms';

@Component({
  selector: 'app-profile-editor',
  templateUrl: './profile-editor.component.html',
  styleUrls: ['./profile-editor.component.css']
})
export class ProfileEditorComponent {
  profileForm = this.fb.group({
    firstName: ['', Validators.required],
    lastName: [''],
    address: this.fb.group({
      street: [''],
      city: [''],
      state: [''],
      zip: ['']
    }),
  });

  constructor(private fb: FormBuilder) { }
}

       FormArray,基于此管理表单或列表的动态组件列表,虽然没有试过但看其模式应该是可以用来做动态表格,或者div块的内容的验证和管理;用到的指令formArrayName 详细参见Angular文档 FormArray

profileForm = this.fb.group({
  firstName: ['', Validators.required],
  lastName: [''],
  address: this.fb.group({
    street: [''],
    city: [''],
    state: [''],
    zip: ['']
  }),
  aliases: this.fb.array([
    this.fb.control(''),
    this.fb.control('')
  ])
});

        可以通过添加getter取值方法来代替操控FormArray对象句柄时的长语句,以达到优化代码的目的.

get aliases() {
  return this.profileForm.get('aliases') as FormArray;
}
addAlias() {
  this.aliases.push(this.fb.control(''));
}
<div formArrayName="aliases">
  <h3>Aliases</h3> <button (click)="addAlias()">Add Alias</button>

  <div *ngFor="let alias of aliases.controls; let i=index">
    <!-- The repeated alias template -->
    <label>
      Alias:
      <input type="text" [formControlName]="i">
    </label>
  </div>
</div>

 以上

 

 类似资料: