[英]Angular 5 + Angular Material Select + Reactive Forms == No initial options displayed
正如标题所说,我有一个反应形式,其中包含多个<mat-select>
。 在初始表单加载时,即使form.value
显示初始选项,也不会显示初始选项。
相关组件:
export class DesJobInfoEditComponent implements OnInit {
...
currentJobData: IJob;
jobTypes: IJobType[];
...
constructor(private fb: FormBuilder) {
...
// Construct forms
this.createForm();
this.initializeForm();
}
createForm() {
this.editJobInfoForm = this.fb.group({
...
JobType: '', // mat-select
...
});
}
initializeForm() {
this.rebuildForm();
}
rebuildForm() {
this.editJobInfoForm.reset({
...
JobType: this.jobTypes[this.currentJobData.JobType].DisplayDesc,
...
});
}
}
相关的HTML:
<mat-form-field fxFlex>
<mat-label>Job Type</mat-label>
<mat-select formControlName="JobType" placeholder="Job Type">
<mat-option *ngFor="let jobType of jobTypes" value="jobType.value">
{{ jobType.DisplayDesc }}
</mat-option>
</mat-select>
</mat-form-field>
加载表单时,选择不显示最初选择的选项,但是,它们设置正确,显然:
Form value { ... "JobType": "0 - Standard", ... }
表单上显示的所有内容都是占位符。
这似乎不应该是这么困难。
我究竟做错了什么?
编辑:
加载模块时会加载this.jobTypes
,它是一个存在于我的数据服务中的BehaviorSubject。 我在这个组件的构造函数中订阅它:
this.data.jobTypes.subscribe(jobTypes => { this.jobTypes = jobTypes });
一些东西
[formControlName]
必须与[formGroup]
一起使用。 如果您不想使用[formControlName]
+ [formGroup]
,则可以使用[formControl]
。
在角度中,将属性指定为value
与[value]
之间存在差异。 当一个属性括在方括号[]
,它被解释为
javascript /
angular模板脚本(我认为与{{}}
相同)。 当它没有括在括号中时,它被解释为一个字符串(即value="jobType.value"
=== [value]="'jobType.value'"
和[value]="jobType.value"
=== value="{{jobType.value}}"
(实际上我认为[value]="jobType.value"
和value="{{jobType.value}}"
之间存在细微差别,但是w / e))。 因此,当您编写<mat-option *ngFor="let jobType of jobTypes" value="jobType.value">
,每个mat-option
的值都是"jobType.value"
,我想,这不是您想要的。 因此,您需要将代码更改为<mat-option *ngFor="let jobType of jobTypes" [value]="jobType.value">
例如
<mat-form-field [formGroup]='editJobInfoForm' fxFlex>
<mat-label>Job Type</mat-label>
<mat-select formControlName="JobType" placeholder="Job Type">
<mat-option *ngFor="let jobType of jobTypes" [value]="jobType.value">
{{ jobType.DisplayDesc }}
</mat-option>
</mat-select>
</mat-form-field>
与您的问题有点无关,为什么同时有createForm()
和initializeForm()
方法? 为什么不简单
constructor(private fb: FormBuilder) {
...
// Construct forms
this.createForm();
}
createForm() {
this.editJobInfoForm = this.fb.group({
...
JobType: this.jobTypes[this.currentJobData.JobType].DisplayDesc,
...
});
}
使用比较功能,因为它...
Step1:显示[compareWith]标签
<mat-form-field>
<mat-select placeholder="Pick item..." formControlName="selectedItem"
[compareWith]="compareFn">
<mat-option *ngFor="let item of items">
{{item.name}}
</mat-option>
</mat-select>
</mat-form-field>
<button (click)="changeValue()">Change value</button>
第2 compareByValue
:声明变量compareFn
和函数compareByValue
,如下所示,无需更改
compareFn: ((f1: any, f2: any) => boolean) | null = this.compareByValue;
compareByValue(f1: any, f2: any) {
return f1 && f2 && f1.name === f2.name;
}
嗨,我知道它太晚了,但我知道一个更简单的解决方案。 您的UI(html)组件已正确描述
在您的打字稿中,您将对象与字符串进行比较,而不会产生任何验证。 所以总是将对象与null进行比较(在验证中)
只需在createForm() { this.editJobInfoForm = this.fb.group({ ... JobType: '', // mat-select ... }); }
createForm() { this.editJobInfoForm = this.fb.group({ ... JobType: '', // mat-select ... }); }
更改JobType: ''
替换为JobType:[null]
Angalural Material compareWith:(o1:any,o2:any)=> boolean from(Angular Material select的API参考)
component.ts
export class ParentOneComponent implements OnInit {
materialFormSample: FormGroup;
constructor() { }
ngOnInit() {
this.configureMaterialFormSample();
}
name: string = 'Emilius Patrin Mfuruki';
toppingList: string[] = ['Extra cheese', 'Mushroom', 'Onion', 'Pepperoni', 'Sausage', 'Tomato'];
selectedToppingList = ['Extra cheese', 'Tomato', 'Onion'];
compareWithFunc = (a: any, b: any) => a == b;
configureMaterialFormSample() {
this.materialFormSample = new FormGroup({
name: new FormControl(this.name),
toppings: new FormControl(this.selectedToppingList)
})
}
onSubmitForm() {
if (this.materialFormSample.valid) {
console.log('submitting Form Content Valid', this.materialFormSample.value);
}
}
}
component.html
<form [formGroup]="materialFormSample" (ngSubmit)="onSubmitForm()" autocomplete="off">
<mat-form-field class="w-100">
<input matInput placeholder="Name" formControlName="name">
</mat-form-field>
<mat-form-field class="w-100">
<mat-label>Toppings</mat-label>
<mat-select formControlName="toppings" multiple [compareWith]="compareWithFunc">
<mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping}}</mat-option>
</mat-select>
</mat-form-field>
<div class="clearfix">
<button type="submit" mat-raised-button color="primary" class="float-right">Submit Form</button>
</div>
</form>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.