【问题标题】:what does formarray.controls in formsarray mean in angular 5?formsarray 中的 formarray.controls 在角度 5 中是什么意思?
【发布时间】:2018-05-03 11:49:05
【问题描述】:

我是 Angular 5 的新手,所以基本上仍在掌握这些概念。以 Angular 关于响应式表单的文档为例(https://angular.io/guide/reactive-forms),给出以下代码:

<div formArrayName="secretLairs" class="well well-lg">
<div *ngFor="let address of secretLairs.controls; let i=index" 
 [formGroupName]="i" >
    <!-- The repeated address template -->
  </div>
  </div>

secretlairs.controls 是什么意思,它是什么?根据角度,这意味着:

重复项的来源是 FormArray.controls,而不是 FormArray 本身。每个控件都是一个地址 FormGroup,正是之前(现在重复)模板 HTML 所期望的。

secretlairs.controls 是否包含任何数据?我可以用任何类型的数据替换这部分,并用从 webapi 获得的数据实例化一个对象本身吗? 例如,而不是

*ngFor="let address of secretLairs.controls

我用

*ngFor="let address of addresses

其中地址是任何类型的,数据是从数据库中获取的。

【问题讨论】:

    标签: angular


    【解决方案1】:

    首先,有三种类型的表单 - FormControlFormGroupFormArray - 都继承自 AbstractControl

    当您使用响应式表单进行验证并在组件的模板中包含formGroupNameformControlNameformArrayName 时,您实际上是在声明式地定义表单控件树和根FormGroup 模型之间的映射。

    例如,给定以下模板:

    <div [formGroup]="formGroup">
        <div formGroupName="personalInfo">
             First Name: <input type="text" formControlName="firstName"><br />
             Last Name: <input type="text" formControlName="lastName"><br />
        </div>
        <div formArrayName="cities">
            Top cities: <input *ngFor="let city of cities; index as i" type="text" [formControlName]="i">
        </div>
    </div>
    

    您正在以声明方式设置用于收集信息的表单映射,最终将生成特定格式的 JSON 对象。例如,给定上述表单模型,formGroup.value 将返回:

    {
       "personalInfo": {
            "firstName: 'John',
            "lastName: 'Smith'
        },
        "cities": [
            "New York",
            "Winnipeg",
            "Toronto"
        ]
     }
    

    在模板中声明表单组的结构后,您需要在组件类中强制创建相应的formGroupformControlformArray。在设置每个表单时,您有机会设置其他参数:

      1. Initial Form Value
      2. Array of synchronous validators
      3. Array of asynchronous validators
    

    这适用于任何抽象控件。

    这是给定上述模板的相应 formGroup 模型的样子:

    export class AppComponent {
      firstName: string,
      lastName: string;
      cities: string[];
      @Input() formGroup: FormGroup;
      constructor(private fb: FormBuilder) {
        // setup initial values
        this.cities = ['New York', 'Winnipeg', 'Toronto'];
        this.firstName = 'John';
        this.lastName  = 'Smith';
    
        // create a formGroup that corresponds to the template
        this.formGroup = fb.group({
          firstName: [this.firstName, Validators.required],
          lastName: [this.lastName, Validators.required],
          cities: fb.array(this.cities.map(t=> fb.control(t, Validators.required)))
        })
      }
    }
    

    要绑定到任何表单的验证标志,您可以使用根 formGroup 和路径字符串(支持点)来查找特定的组、控件或数组。

    例如:

    <div *ngIf="formGroup.get('firstName').errors.required">First Name is Required</div>
    

    希望这能说明问题。

    [编辑]

    更好的是,鉴于 Reactive Forms 就是在模板中以声明方式设置模型,并在组件类中强制映射相同的模型,您应该考虑定义 JSON 模型并改用它。

    例如,假设我们有一个自定义模型MyModel,它具有firstName 属性、lastName 属性和cities 属性。组件类看起来像这样:

     export class AppComponent {
      @Input() model: MyModel;
      @Output() modelChange: EventEmitter<MyModel>;
    
      @Input() formGroup: FormGroup;
      constructor(private fb: FormBuilder) {
        this.model = new EventEmitter<MyModel>();
        // create a formGroup that corresponds to the template
        this.formGroup = fb.group({
          firstName: [this.model.firstName, Validators.required],
          lastName: [this.model.lastName, Validators.required],
          cities: fb.array(this.model.cities.map(t=> fb.control(t, Validators.required)))
        });
      }
    
      onSubmit() {
         if (this.formGroup.valid) {
            this.model = this.formGroup.value;
            this.modelChange.next(this.model);
         }
      }
    }
    

    【讨论】:

    • 您好,感谢您的意见。这无疑使整个概念的运作方式更加清晰。但是,您能向我解释一下 formarray.controls 具体指的是什么吗? formarray.controls 中的每个控件是否都引用了表单组?我可以用数据模型而不是控件替换这部分吗?
    • 我给出的例子是数据模型(而不是控制模型)
    • 我明白了,所以只是指出没有必要总是使用控制模型,对吧?这意味着如果我选择使用数据模型,我仍然可以将用户输入绑定到表单字段吗? (通过您在示例中提到的表单控件名称)
    • 是的,没错。您可以绑定到常规 Data 模型或 Control 模型。
    • 这很好地解释了这个问题。谢谢你。我会赞成这个作为正确答案
    猜你喜欢
    • 2015-03-21
    • 2018-07-11
    • 2019-10-16
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 2017-03-16
    • 2011-08-12
    • 2017-06-11
    相关资源
    最近更新 更多