首页 > 解决方案 > Angular formControl - 在 ngfor 循环的特定行中设置一个值

问题描述

请在 stackblitz 参考完整代码

将第一列下拉菜单修改为模型时,观察到第三列显示模型列表。

单击添加行按钮->第二行,将第一列下拉列表修改为系统->观察到第二行的第三列下拉列表也更改为系统列表。但是,它也修改了其他行的第三列。有没有办法只修改第二行的第三列?

所以 formControlName 在 ngFor 循环中是相同的,我想观察 formControl 中的变化并仅为该行更新第三列下拉值(不是所有行)

stackblitz

标签: angularangular6angular7ngforangular-forms

解决方案


您需要使用 FormArray。我想你想做一些像

formArray:FormArray=new FormArray([this.newLine()]);

newLine() //This funcrion is WORNG, see update 2
{
   return this.formBuilder.group({
     onValues: [
        { value: "" },
        [Validators.required, Validators.pattern(/^[+-]?\d+(\.\d+)?$/)]
      ],
      ruleTypeValues: [{ value: "" }],
      getType: [{ value: "" }], 
      filterValue: [{ value: "" }]
   })
}
addLine()
{
   this.formArray.push(this.newLine())
}
removeLine(index)
{
   this.formArray.removeAt(index)
}

要进行管理,请使用 [formGroup] 查看 formArray.controls

<form class="form" [formGroup]="formArray">
      <div *ngFor="let group of formArray.controls;let i=index" [formGroup]="group" class="rows">
        <div class="clr-select-wrapper">
          <select formControlName="getType">
            <ng-container *ngFor="let val of rootName">
              <option [ngValue]="val">{{ val }}</option>
            </ng-container>
          </select>
        </div>
        <div class="clr-select-wrapper">
          <select formControlName="ruleTypeValues">
            <ng-container *ngFor="let val of ruleType">
              <option [ngValue]="val">{{ val }}</option>
            </ng-container>
          </select>
        </div>
        <div class="clr-select-wrapper" *ngIf="getValues.length > 0">
          <select formControlName="onValues">
            <ng-container *ngFor="let val of getValues">
              <option [ngValue]="val">{{ val }}</option>
            </ng-container>
          </select>
        </div>
        <input
          *ngIf="getValues.length === 0"
          type="text"
          formControlName="filterValue"
          class="text"
          placeholder="sdf"
        />
        <div class="row-button">
          <button  (click)="addLine()">Add row</button>
          <button  (click)="removeLine(i)">Remove row </button>
          <button (click)="addBlock(row)">Add block</button>
        </div>
      </div>
    </form>

更新订阅 formGroup 的 valueChanges 我们需要更改函数 newLine 并分两步完成:

newLine()
{
   const group=this.formBuilder.group({
     onValues: [
        { value: "" },
        [Validators.required, Validators.pattern(/^[+-]?\d+(\.\d+)?$/)]
      ],
      ruleTypeValues: [{ value: "" }],
      getType: [{ value: "" }], 
      filterValue: [{ value: "" }]
   })
   group.valuesChange.subscribe((res:any)=>{
     ..here the code
   }
   //or, if we only want to check, e.g. "getType"
   group.get('getType').valueChange.subscribe((res:any)=>{
      ..here the code
   }
   return group;
}

或者,在创建表单之后,例如在 ngOnInit

ngOnInit()
{
    this.formArray.valueChanges.subcribe((res:any)=>{
       ..here the code..
    }
}

Update2 newLine 函数出错!!!

必须像

newLine(){
   const group=this.formBuilder.group({
     onValues: ["",
        [Validators.required, Validators.pattern(/^[+-]?\d+(\.\d+)?$/)]
      ],
      ruleTypeValues: [""],
      getType: [""], 
      filterValue: [""]
   })
   return group
}

推荐阅读