Angular 6 无法从提供的对象中自动选择/绑定下拉列表值

Posted

技术标签:

【中文标题】Angular 6 无法从提供的对象中自动选择/绑定下拉列表值【英文标题】:Angular 6 cannot automatically select/bind dropdown list value from supplied object 【发布时间】:2018-11-26 23:02:39 【问题描述】:

我从服务中获取一个国家对象并将其绑定到一个具有国家下拉列表的表单。从服务中检索该国家/地区后,该国家/地区并未显示为选中状态,但所有其他数据均显示正常,包括绑定到下拉列表的字符串性别字段。我可以从列表中手动选择国家。如何自动显示所选国家/地区?

个人详细信息.component.html

    <form [formGroup]="form" (submit)="doSave(form.values)">
        <mat-card class="main-card">

            <mat-card-content>
                <p>Personal Details</p>
                <mat-form-field class="full-width-input">
                  <input matInput placeholder="Given name" formControlName="givenName" >
                </mat-form-field>
                <mat-form-field class="full-width-input">
                  <input matInput placeholder="Surname" formControlName="surname" required>
                </mat-form-field>
                <mat-form-field class="full-width-input">
                    <mat-select placeholder="Select gender" formControlName="gender" required>
                        <mat-option *ngFor="let g of genders" [value]="g">g</mat-option>
                    </mat-select>      
                </mat-form-field>
                <mat-form-field class="full-width-input">
                    <mat-select placeholder="Select country of birth" formControlName="countryBorn" required>
                      <mat-option *ngFor="let country of countries" [value]="country">country.name</mat-option>
                    </mat-select>      
                </mat-form-field>
            </mat-card-content>

        </mat-card>
    </form>

personal-details.component.ts

  countries = [
    new Country('1100', 'Australia', '1'),
    new Country('1201', 'New Zealand', '160'),
    new Country('3105', 'Malta', '140')
  ];
  genders = ['F', 'M'];

  ngOnInit() 
    this.form = this.fb.group(
      givenName: ['', Validators.required],
      surname: ['', Validators.required],
      gender: ['', Validators.required],
      countryBorn: ''
    );

    this.response = this.applicantService.getDetails()
      .pipe(take(1), tap(resp => 
        this.form.patchValue(resp.personalDetails);
      ));

  

域:

export class PersonalDetails 
  givenName: string;
  surname: string;
  gender: string;
  countryBorn: Country;

  constructor(givenName?: string, surname?: string, gender?: string, countryBorn?: string) 
    this.id = id;
    this.surname = surname;
    this.gender = gender;
    this.countryBorn = countryBorn;
  
  

export class Country 
  id: string;
  name: string;
  displayOrder: string;

  constructor(id?: string, name?: string, displayOrder?: string) 
    this.id = id;
    this.name = name;
    this.displayOrder = displayOrder;
  

数据:

incoming value from service:  "surname": "Oliver", "givenName": "Bert", "gender": "M", "countryBorn":  "id": "1201", "name": "New Zealand", "displayOrder": "160" , "birthdate": "1990-04-21" 

Form value on load (form.value | json ) =   "givenName": "Bert", "surname": "Oliver", "gender": "M", "countryBorn":  "id": "1201", "name": "New Zealand", "displayOrder": "160" 

谢谢

【问题讨论】:

每隔一天就会有人问这个问题。您个人中的 Country 对象,即使它与国家/地区数组中的一个国家具有相同的属性,对其中任何一个都不是 ===。它需要。找到与person中的country具有相同ID的数组的country,将person的country替换为数组中的那个country。或者只是使用国家 ID 作为您选择的值。 【参考方案1】:

Angular 使用对象标识来选择选项,还提供了特殊的输入属性来自定义默认的选项比较算法:compareWith

html

<mat-select ... formControlName="countryBorn" [compareWith]="compareFn">
                                              ^^^^^^^^^^^^^^^^^^^^^^^^^   

ts

compareFn(c1: Country, c2: Country) 
  return c1.id === c2.id;
            

Ng-run Example

【讨论】:

太棒了!在这上面花了很多时间,多亏了你,它才有效。干杯【参考方案2】:

resp.personalDetails.countryBorn 设置为列表中的实际对象,然后再将其分配给表单(因为对象比较 ...===... 始终为假,Angular将无法匹配和选择它)

resp.personalDetails.countryBorn = this.countries.find(country=> resp.personalDetails.countryBorn.id);

或者单独设置id作为值

<mat-option *ngFor="let country of countries" [value]="country.id">country.name</mat-option>

数据将只有国家 ID 而不是整个对象。

 "surname": "Oliver", "givenName": "Bert", "gender": "M", "countryBorn": "1201", "name": "New Zealand", "displayOrder": "160" , "birthdate": "1990-04-21" 

否则您可能需要使用 compareWith 定义自己的比较函数:https://angular.io/api/forms/SelectControlValueAccessor#caveat-option-selection

【讨论】:

以上是关于Angular 6 无法从提供的对象中自动选择/绑定下拉列表值的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2 @Input - 如何从父组件绑定子组件的 ID 属性?

从列表中接收模型并显示属性[javascript] [angular 7]

Angular 6 - 无法订阅从服务返回的数据

从 typescript angular 6 中选择默认选项值

ngFor 无法通过与 @Input 的组件绑定来迭代另一个组件

下拉菜单无法从对象中提取数值(Angular 4)