Angular 6 无法自动 select/bind 提供对象的下拉列表值
Angular 6 cannot automatically select/bind dropdown list value from supplied object
我从服务中获取国家对象并将其绑定到具有国家下拉列表的表单。从服务中检索后,国家/地区未显示 selected,但所有其他数据都显示正常,包括绑定到下拉列表的字符串性别字段。不过,我可以从列表中手动 select 国家。如何自动将国家/地区显示为 selected?
个人-details.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>
个人-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" }
谢谢
Angular 将对象标识用于 select 选项,还提供特殊输入 属性 来自定义默认选项比较算法:compareWith:
html
<mat-select ... formControlName="countryBorn" [compareWith]="compareFn">
^^^^^^^^^^^^^^^^^^^^^^^^^
ts
compareFn(c1: Country, c2: Country) {
return c1.id === c2.id;
}
要么将 resp.personalDetails.countryBorn 设置为列表中的实际对象,然后再将其分配给表单(因为对象比较 {...}==={...}始终为 false,Angular 将无法匹配并匹配 select)
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
我从服务中获取国家对象并将其绑定到具有国家下拉列表的表单。从服务中检索后,国家/地区未显示 selected,但所有其他数据都显示正常,包括绑定到下拉列表的字符串性别字段。不过,我可以从列表中手动 select 国家。如何自动将国家/地区显示为 selected?
个人-details.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>
个人-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" }
谢谢
Angular 将对象标识用于 select 选项,还提供特殊输入 属性 来自定义默认选项比较算法:compareWith:
html
<mat-select ... formControlName="countryBorn" [compareWith]="compareFn">
^^^^^^^^^^^^^^^^^^^^^^^^^
ts
compareFn(c1: Country, c2: Country) {
return c1.id === c2.id;
}
要么将 resp.personalDetails.countryBorn 设置为列表中的实际对象,然后再将其分配给表单(因为对象比较 {...}==={...}始终为 false,Angular 将无法匹配并匹配 select)
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