首页 > 解决方案 > 如何解决链接到输入字段的 Angular FormArray 和 mat-select 选项?

问题描述

我有一个场景,用户可以打开mat-select并从下拉列表中选择一个选项。在他选择后,将显示一个隐藏的表格供他填写。静态(一个)模板一切正常。现在,我们决定将mat-select和相应的模板链接到 Angular 中的选项formArray。我现在面临两个问题: 1-所有mat-select生成的表单中的所有 s 都侦听相同的事件(用户选择的选项。也就是说,当您更改索引 1的mat-select索引 0 时,会对您的2- 所有生成的表单都带有链接到用户从第一次选择中选择的选项的模板(索引中的 0 )。formArraymat-selectformArray

没有语法错误。

我猜这个问题源于我定义的一个全局变量,它决定显示forms或不显示:(isPremiumAmountSelected在下面的代码中)。我不喜欢拆分我的组件来使用@Input@Output. 我需要一个基于下面共享的解决方案。(有很多相关的东西取决于这个)。

isPremiumAmountSelected: boolean = false; 
  FixedProductPrice: Boolean = undefined; 
  OneFactorPricingCarValue: Boolean = undefined; 
  MultiFactorPricingCarValueCarModel: Boolean = undefined;

  ToggledPremiumAmountTypeDropDownOptions(data){
    this.isPremiumAmountSelected = true; 
    if(Object.is(data.value, 1)){
      this.FixedProductPrice = true; 
      this.OneFactorPricingCarValue = false; 
      this.MultiFactorPricingCarValueCarModel = false; 
    }if(Object.is(data.value, 2)){
      this.OneFactorPricingCarValue = true; 
      this.FixedProductPrice = false; 
      this.MultiFactorPricingCarValueCarModel = false;
    }if(Object.is(data.value, 3)){
      this.MultiFactorPricingCarValueCarModel = true; 
      this.FixedProductPrice = false; 
      this.OneFactorPricingCarValue = false;
    }
  }
<div formArrayName="formArray" *ngFor="loop goes here; let i = index">
    <div [formGroupName]="i">
    <mat-form-field appearance="outline" *ngIf="options">
        <mat-label>Available Types</mat-label>
        <mat-select 
        (ngModel)="selectedPremiumAmountOptionValue" 
        (onSelectionChange)="ToggledPremiumAmountTypeDropDownOptions($event)"
        formControlName="control">
            <mat-option *ngFor="let option of options"
            (click)="ToggledPremiumAmountTypeDropDownOptions(option)" 
            [value]="option?.value">
            {{option?.viewValue}}
            </mat-option>
        </mat-select>                  
        </mat-form-field>
     <span *ngIf="isPremiumAmountSelected">
            <div *ngIf="FixedProductPrice"> Template 1 goes here</div>
            <div *ngIf="OneFactorPricingCarValue"> Template 2 goes here</div>
            <div *ngIf="MultiFactorPricingCarValueCarModel"> Template 3 goes here</div>
     </span>
    </div>
</div>

更新

发布我的问题几个小时后,我能够解决它。我的方法类似于下面的@Eliseo答案。可能更直接。

第一步:删除TS方法和golabl变量

这两个应该删除:ToggledPremiumAmountTypeDropDownOptions()方法和isPremiumAmountSelected变量。其他三个变量应该保留。

第二步:调整ngIf模板中的逻辑

为了防止多听众对同一事件的问题,我在每次迭代中访问所选选项的值都*ngIf在其中。(删除托管的跨度,isPremiumAmountSelected并为您拥有的每个条件模板放在下面的逻辑)另外,不要忘记清除上的方法mat-select(没有任何方法应该是正常的)。

类似以下的*ngIfs 将有条件地隐藏和显示模板:

*ngIf="productCreationForm.get('formArrayName')['controls'][i].get('mat-select-formControlName').value === 'x'"

我对要显示的每个条件模板都执行此操作。

也就是说我正在验证模板中的值。有了这个,我摆脱了全局变量 isPremiumAmountSelected,这在基于第一次选择的每次迭代中总是正确的。

希望这是说明性的。我认为下面@Eliseo的方法是可行和正确的。

标签: javascriptangulartypescriptangular-material

解决方案


通常,要管理属于 FormGroup 的 FormGroup 的 FormArray,您有一个 getter 来获取 formArray

get myFormArray()
{
     return this.myForm.get('myFormArray') as FormArray
}

<form [formGroup]="myFormGroup">
  <!--use formArrayNem-->
  <div formArrayName="myFormArray">
      <!--see that we use the "getter" before and iterate over "controls"-->
      <!--see the [formGroupName]="i" IN the own loop-->
      <div *ngFor="let group of myFormArray.controls;let i=index"
              [formGroupName]="i">
            <!--here you use formControlName to input the control, e.g.-->
            <input formControlName="control">

            <!--to know the value of control you can use, e.g.-->
            <div *ngIf="formArray.value[i].control==2">is two</div>
             <!-- or -->
            <div *ngIf="formArray.at(i).value.control==2">is two</div>
             <!-- or -->
            <div *ngIf="formArray.at(i).get('control').value==2">is two</div>
      </div>
  </div>
</form>

您无需使用三个变量即可知道是 fixedProduction、onFactor 还是 multipleFactor。如果要使用三个变量,则需要使用 tre 数组,但您可以看到是不必要的 (onSelectionChange) 事件。

注意:您使用的是(ngModel)' -not exist (ngModel)- if you want to say [ngModel]` 请记住,如果您使用的是 FormArrays 或 FormControl,则不应使用ngModel-,

注意2:在我的回答中,我使用了一些类似

form=new FormGroup({
    formArray:new FormArray([this.getGroup(),this.getGroup()])
  })
  get formArray()
  {
    return this.form.get('formArray') as FormArray
  }
  getGroup()
  {
    return new FormGroup({
      control:new FormControl(),
      fixedPrice:new FormControl(),
      oneFactor:new FormControl(),
    })
  }

不知道你在用什么


推荐阅读