Angular Reactive Forms:动态选择下拉值不绑定 [英] Angular Reactive Forms: Dynamic Select dropdown value not binding

查看:20
本文介绍了Angular Reactive Forms:动态选择下拉值不绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

public ngOnInit() {this.factsForm = this.formbuilder.group({关联主体:this.formbuilder.array([]),参考主体:this.formbuilder.array([])});//这两种方法的数据都来自外部来源...var responseData =//HTTP 源...//将检索到的数据推送到表单中this.initPrincipals(responseData[0]);//将静态数据推入表单this.initStaticData(responseData[1]);}公共 initPrincipals(principals?: IAssociatedPrincipal[]): FormArray {principals.forEach((principal) => {this.relatedPrincipals.push(this.createPrincipalFormGroup(principal));});}公共 initStaticData(响应:IReferencePrincipal[]){response.forEach((principal) => {this.referencePrincipals.push(this.formbuilder.control({代码:principal.code,canHaveLead:principal.canHaveLead,isDuplicate: 假}));});}公共 createPrincipalFormGroup(主体:IAssociatedPrincipal){返回 this.formbuilder.group({代码:principal.code,canHaveLead:假,isDuplicate: 假});}公共获取相关主体():FormArray {返回 this.factsForm.get('relatedPrincipals') 作为 FormArray;}公共获取 referencePrincipals(): FormArray {将 this.factsForm.get("referencePrincipals") 作为 FormArray 返回;}

HTML:

 
<div formArrayName="relatedPrincipals"><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>--选择--</option><option *ngFor="let refPrincipal of referencePrincipals.controls" [ngValue]="refPrincipal">refPrincipal.value.code</option></选择>

</表单>

感谢您的任何反馈!

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

解决方案

演示中的问题

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

  • 没有分配给 selectformControlName.
  • 您将对象绑定到选择的选项.

对于第一个问题

因为您正在循环遍历 associatedPrincipals 以动态显示下拉列表.而 associatedPrincipals 是一个 formArray ,可以考虑如下:

associatedPrincipals = {0":表单控件,1":表单控件}

因此,您可以简单地将在 *ngFor 表达式中定义的 i 分配给 formControlName.

<option value=null disabled selected hidden>--选择--</option><option *ngFor="let refPrincipal of referencePrincipals.controls"[ngValue]="refPrincipal.value">{{ refPrincipal.value.code }}</option></选择>//告诉 angular 如何比较两个对象compareFn(item1, item2): 布尔 {返回 item1 &&项目 2 ?item1.code === item2.code : item1 === item2;}

参考文档并修复demo 了解详情.

I have two arrays of data: AssociatedPrincipals (previously saved data) and ReferencePrincipals (static data to populate in dropdown controls). I'm struggling to get the previous value from AssociatedPrincipals to be displayed/selected in a dynamic amount (most examples use a single dropdown) of dropdowns on page load.

I'm not certain how to set up the form (code behind and HTML), especially setting the Select's formControlName. Currently, the static values in each dropdown populate, but I cannot get the selected value to bind properly.

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;
    }

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>

I appreciate any feedback!

EDIT: Added Plunker showing the issue: https://embed.plnkr.co/XMLvFUbuc32EStLylDGO/

解决方案

Problems in your demo

Based on the demo you provided, There are several problems as listed below:

  • There is no formControlName assigned to select.
  • You are binding object to select's option.

For the first problem

Since you are looping through associatedPrincipals to show dropdownlist dynamically. And associatedPrincipals which is a formArray which can consider as below:

associatedPrincipals = {
  "0": FormControl,
  "1": FormControl
}

So you can simply assign i which is defined at *ngFor expression to formControlName.

<select formControlName="{{i}}" style="margin-top: 10px">
   ...
</select>

For the second problem

While binding object to option, Angular will compare default value and option's value by object instance by default.

You can set same instance(get from value of referencePrincipals's formControls) to formControl of associatedPrincipals(as @Fetra R.'s answer). But this is not the most convenient way since you have to take some logic to keep the same instance of an object.

Here I would give you another solution which is using compareWith directive designed specifically for your current situation, see docs.

Using compareWith directive, you just need to implement a compareFun to tell angular how to consider two objects(with different instances) as the same.Here yo can include comparing object instance and comparing object fields at the same time.

<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;
}

Refer docs and fixed demo to learn detail about it.

这篇关于Angular Reactive Forms:动态选择下拉值不绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆