【问题标题】:How to reuse FormGroup to fill out same field in different forms in Angular 9?如何重用 FormGroup 在 Angular 9 的不同表单中填写相同的字段?
【发布时间】:2020-11-13 04:51:43
【问题描述】:

我正在创建一个表单来从 Angular 中的字段输入中捕获数据。

假设我有(学生、教师、管理人员)填写表格。

他们(2 个或全部)共享一些可重复使用的字段(生日、名字、姓氏)和其他所有字段(工作地址、家庭地址、邮寄地址)不同且仅 2 个(学生)不同的字段ID,教师 ID)。

是否可以为此目的设置多个表单组?如果他们每个人都有很多字段,我将如何处理?

【问题讨论】:

    标签: angular forms crud formgroups


    【解决方案1】:

    这可以通过 Model Based Reactive Forms 使用我在 npm 上找到的直观库 @rxweb/reactive-form-validators 来实现

    npm i @rxweb/reactive-form-validators

    首先创建一个模型类,该模型类具有您在表单组中需要的属性,如下所示

    import {  prop, } from "@rxweb/reactive-form-validators"
    export class User {
    
        @prop()
        firstName: string;
    
        @prop()
        lastName: string;
    
        @prop()
        emailAddress: string;
    
    }
    

    @prop() 定义了一个属性,该属性可用于使用RxFormBuilderformGroup 方法初始化一个formControl。该模型可以稍后在其他组件中恢复这些属性并制作一个formGroup,而无需多次编写相同的代码

    import { Component, OnInit } from '@angular/core';
    import { FormGroup } from "@angular/forms"
    
    import { RxFormBuilder } from '@rxweb/reactive-form-validators';
    
    import { User } from './user.model';
    
    @Component({
        selector: 'app-user-add',
        templateUrl: './user-add.component.html'
    })
    export class UserAddComponent implements OnInit {
    
        userFormGroup: FormGroup
    
        constructor(
            private formBuilder: RxFormBuilder
        ) { }
    
        ngOnInit() {
            let user = new User();
            this.userFormGroup = this.formBuilder.formGroup(user);
        }
    }
    
    

    组件Html文件如下:

    <form *ngIf="userFormGroup" [formGroup]="userFormGroup">
      <div class="form-group">
        <label>FirstName</label>
        <input type="text" formControlName="firstName" class="form-control" />
      </div>
      <div class="form-group">
        <label>LastName</label>
        <input type="text" formControlName="lastName" class="form-control" />
      </div>
      <div class="form-group">
        <label>Email Address</label>
        <input type="text" formControlName="emailAddress" class="form-control" />
      </div>
      <button [disabled]="!userFormGroup.valid" class="btn btn-primary">
        Submit
      </button>
    </form>
    
    

    这是stackblitz上的完整示例

    如果您想扩展该类并向 formGroup 添加额外的属性,您可以使用同一库中提供的class abstraction 功能,同时它带有许多内置验证器,可以轻松执行验证

    要了解更多关于这种方法的信息,请参考Simplified Reactive Forms

    【讨论】:

      【解决方案2】:

      如果您使用的是响应式表单,它可能看起来很诱人,但当您意识到 FormGroup 只是一个 JS 对象时,这会很容易。因此,您可以像使用任何其他 JS 对象一样使用它们。

      更简单的方法是在服务中实现一个方法,并利用您的 JS/TS 对象知识:

      private commonFields;
      private roleBasedFields;
      private addressForm;
      
      constructor() {
        this.commonFields = {
          firstName: '',
          lastName: ['', Validators.required],
          birthday: [null, Validators.required]
        };
      
        this.addressForm = {
           street: '',
           streetNo: null,
           zip: null,
           city: '',
           // and so on...
        };
      
        this.roleBasedFields = {
          student: {
            homeAddress: addressForm,
            // add other fields related to student here
          },
          faculty: {
            workAddress: addressForm,
            // add other fields here
          },
          administration: {
            mailingAddress: {
              ...addressForm,
              department: ['', Validators.required]
              // if the address object is different for a certain role, you can add them like this
            },
            // add other fields here
          },
      };
      
      }
      
      buildForm(role: 'student' | 'faculty' | 'administration'): FormGroup {
        return new FormGroup({
          ...this.commonFields,
          ...this.roleBasedFields[role]
        });
      }
      

      在组件中,根据您希望它的实现方式,像这样使用它:

      someForm: FormGroup;
      formArray: FormArray;
      
      ngOnInit() {
        this.someForm = this.thatServiceAbove.buildForm('student');
      
        // if it goes in an array
        this.formArray = new FormArray([]);
      }
      
      // method to push the FormGroup in a FormArray:
      generateForm(role: 'student' | 'faculty' | 'administration') {
         this.formArray.push(this.thatServiceAbove.buildForm(role));
      }
      

      你明白了:D

      【讨论】:

        猜你喜欢
        • 2023-03-08
        • 2011-04-05
        • 1970-01-01
        • 1970-01-01
        • 2017-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多