代码之家  ›  专栏  ›  技术社区  ›  physicsboy

使用*ngFor动态表单并从中提交值

  •  0
  • physicsboy  · 技术社区  · 7 年前

    stackblitz 作为向导。

    然而,我正在努力掌握这一切是如何在我的应用程序的角度和材料特性中工作的。

    html

    <form id="myForm" [formGroup]="thisIsMyForm">
      <mat-card [formGroup]="x" *ngFor="let x of data; let i = index">
        <mat-form-field>
          <label for="{{x.name}}">Name</label>
          <input formControlName="name" id="{{x.name}}" matInput value="{{x.name}}">
        </mat-form-field>
        <mat-form-field>
          <label for="{{x.type}}">Type</label>
          <input formControlName="type" id="{{x.type}}" matInput value="{{x.type}}"/>
        </mat-form-field>
      </mat-card>
    </form>
    

    ts

    import { Component, ViewChild } from '@angular/core';
    import {MatSnackBar} from '@angular/material';
    import {FormArray, FormBuilder, FormGroup, Validators} from '@angular/forms';
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent  {
      thisIsMyForm: FormGroup
    
      data = [
        {name:"one", type:"one"},
        {name:"two", type:"two"},
        {name:"three", type:"three"},
      ];
    
      constructor(private formBuilder: FormBuilder) {}
    
      onSubmit() {
        // Here I would like to be able to access the values of the 'forms'
      }
    
    }
    
    2 回复  |  直到 7 年前
        1
  •  10
  •   Marshal    6 年前

    *ngFor 这是一个挑战。我会尽我所能陪你度过难关。

    formArrayName this.formBuild.array([]) ... 随便你怎么说,我刚用过 格式名称 用于演示目的。

    在使用空数组调用实例化表单之后 this.buildForm()

    constructor(private formBuilder: FormBuilder) {
        this.thisIsMyForm = new FormGroup({
          formArrayName: this.formBuilder.array([])
        })
    
        this.buildForm();
      }
    

    在你的 buildForm() 迭代你的 data[] 并为每个索引推送控件,同时指定默认值和默认状态“禁用”。

     buildForm() {
        const controlArray = this.thisIsMyForm.get('formArrayName') as FormArray;
    
        Object.keys(this.data).forEach((i) => {
          controlArray.push(
            this.formBuilder.group({
              name: new FormControl({ value: this.data[i].name, disabled: true }),
              type: new FormControl({ value: this.data[i].type, disabled: true })
            })
          )
        })
    
        console.log(controlArray)
      }
    

    请注意: name 和 type

    0: FormGroup
    1: FormGroup
    2: FormGroup
    

    thisIsMyForm 你刚刚创造了。

    • 起源:
    • 儿童: 格式名称
    • 孙女: i as formGroupName

    孙子很重要,因为它与的控制台日志相匹配 controlArray.controls 在上一步中

    <form id="myForm" [formGroup]="thisIsMyForm">
        <div [formArrayName]="'formArrayName'">
            <mat-card *ngFor="let x of data; let i = index">
                <div [formGroupName]="i">
    

    基于控件禁用状态创建编辑和保存按钮

       <button *ngIf="formControlState(i)" (click)="toggleEdit(i)">Enable Edit</button>
        <button *ngIf="!formControlState(i)" (click)="toggleEdit(i)">Save</button>
    

    在组件中创建方法以接收索引作为参数,并处理隐藏按钮和切换输入字段启用和禁用状态的逻辑。

    toggleEdit(i) {
        const controlArray = this.thisIsMyForm.get('formArrayName') as FormArray;
        if(controlArray.controls[i].status === 'DISABLED'){
          controlArray.controls[i].enable()
        }else{
          controlArray.controls[i].disable()
        }
      }
    
      formControlState(i){
         const controlArray = this.thisIsMyForm.get('formArrayName') as FormArray;
         return controlArray.controls[i].disabled
      }
    

    <button [disabled]="thisIsMyForm.get('formArrayName').enabled" (click)="onSubmit()">Submit Form</button>
    
    onSubmit() {
        // Here I would like to be able to access the values of the 'forms'
        console.log(this.thisIsMyForm.value)
      }
    

    闪电战

    https://stackblitz.com/edit/dynamic-form-ngfor-otbuzn?embed=1&file=src/app/app.component.ts

        2
  •  0
  •   Jacopo Sciampi    7 年前

    QueryList :

    您的html(这是一个示例):

    <ng-container *ngFor="let x of data; let i = index">
      <div class="ctr">
        <span #names class="item">{{x.name}}</span>
        <span #types class="item">{{x.type}}</span>
        <span class="button" (click)="showData(i)">Show data</span>
      </div>
    
    </ng-container>
    
    <h2>Selected values: </h2>
    Selected name: {{selectedName}} <br>
    Selected type: {{selectedType}}
    

    一些css只是用于样式

    .ctr{
      display: flex;
      flex-direction: row;
      margin-bottom: 20px;
    }
    
    .item{
      margin-right:40px;
    }
    
    .button{
      border: 1px solid black;
      padding: 2px 5px 2px 5px;
      cursor: pointer;
    }
    

    import { Component, QueryList, ViewChildren } from '@angular/core';
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent  {
      @ViewChildren('names') names:QueryList<any>;
      @ViewChildren('types') types:QueryList<any>;
    
      selectedName: string;
      selectedType: string;
    
      data = [
        {name:"one", type:1},
        {name:"two", type:2},
        {name:"three", type:3},
      ];
    
      showData(index){
        let namesArray = this.names.toArray();
        let typesArray = this.types.toArray();
    
        this.selectedName = namesArray[index].nativeElement.innerHTML;
        this.selectedType = typesArray[index].nativeElement.innerHTML;
      }
    }
    

    https://stackblitz.com/edit/angular-j2n398?file=src%2Fapp%2Fapp.component.ts