角度反应表单:动态选择下拉值不绑定

dot*_*kow 5 javascript angular angular-reactive-forms

我有两个数据数组:AssociatedPrincipals(以前保存的数据)和ReferencePrincipals(静态数据填充在下拉控件中).我很难从AssociatedPrincipals中获取先前的值,以便在页面加载时以动态数量(大多数示例使用单个下拉列表)显示/选择下拉列表.

我不确定如何设置表单(代码隐藏和HTML),特别是设置Select的formControlName.目前,每个下拉列表中的静态值都会填充,但我无法正确绑定所选值.

public ngOnInit() {
    this.factsForm = this.formbuilder.group({
        associatedPrincipals: this.formbuilder.array([]),
        referencePrincipals: this.formbuilder.array([])
    });

    // Data for both of these methods comes from external source...
    var responseData = // HTTP source...
    // Push retrieved data into form
    this.initPrincipals(responseData[0]);
    // Push static data into form
   this.initStaticData(responseData[1]);
}

public initPrincipals(principals?: IAssociatedPrincipal[]): FormArray {
    principals.forEach((principal) => {
 this.associatedPrincipals.push(this.createPrincipalFormGroup(principal));
    });
}

public initStaticData(response: IReferencePrincipal[]) {
   response.forEach((principal) => {
      this.referencePrincipals.push(
           this.formbuilder.control({
                code: principal.code,
                canHaveLead: principal.canHaveLead,
                isDuplicate: false
              }));
        });
}

public createPrincipalFormGroup(principal: IAssociatedPrincipal) {
        return this.formbuilder.group({
            code: principal.code,
            canHaveLead: false,
            isDuplicate: false
        });
    }

public get associatedPrincipals(): FormArray {
        return this.factsForm.get('associatedPrincipals') as FormArray;
    }

    public get referencePrincipals(): FormArray {
        return this.factsForm.get("referencePrincipals") as FormArray;
    }
Run Code Online (Sandbox Code Playgroud)

HTML:

 <form novalidate [formGroup]="factsForm">
        <div formArrayName="associatedPrincipals">
             <div *ngFor="let associatedPrincipal of associatedPrincipals.controls; let i=index;" [formGroupName]="i" >
                <select class="form-control create-input"
                        formControlName="i">
                     <option value=null disabled selected hidden>--Select--</option>
                       <option *ngFor="let refPrincipal of referencePrincipals.controls" [ngValue]="refPrincipal">refPrincipal.value.code</option>
                 </select>
             </div>
         </div>
    </form>
Run Code Online (Sandbox Code Playgroud)

我感谢任何反馈!

编辑:添加了Plunker显示问题: https ://embed.plnkr.co/XMLvFUbuc32EStLylDGO/

Pen*_*gyy 9

演示中的问题

根据您提供的演示,有以下几个问题:

  • 没有formControlName分配到select.
  • 您是绑定对象以选择选项.

对于第一个问题

因为您循环associatedPrincipals显示动态显示下拉列表.而且associatedPrincipals这是一个formArray可以如下考虑:

associatedPrincipals = {
  "0": FormControl,
  "1": FormControl
}
Run Code Online (Sandbox Code Playgroud)

所以你可以简单地分配i*ngFor表达式中定义的内容formControlName.

<select formControlName="{{i}}" style="margin-top: 10px">
   ...
</select>
Run Code Online (Sandbox Code Playgroud)

对于第二个问题

虽然绑定对象option,角将比较默认值,并option通过"价值对象实例默认.

您可以将相同的实例(从referencePrincipals's formControls的值获取)设置为formControl associatedPrincipals(如@Fetra R.的答案).但这不是最方便的方法,因为你必须采取一些逻辑来保持对象的同一个实例.

在这里,我将为您提供另一种解决方案,即使用compareWith专门针对您当前情况而设计的指令,请参阅文档.

使用compareWith指令,你只需要实现一个compareFun告诉的角度如何考虑两个对象(具有不同的实例)作为same.Here哟可以包括comparing object instancecomparing object fields在同一时间.

<select formControlName="{{i}}" style="margin-top: 10px" [compareWith]="compareFun">
  <option value=null disabled selected hidden>--Select--</option>
  <option *ngFor="let refPrincipal of referencePrincipals.controls"
     [ngValue]="refPrincipal.value">{{ refPrincipal.value.code }}</option>
</select>

// tell angular how to compare two objects
compareFn(item1, item2): boolean {
  return item1 && item2 ? item1.code === item2.code : item1 === item2;
}
Run Code Online (Sandbox Code Playgroud)

请参阅文档和修复演示以了解有关它的详细信息.