Comme le titre l'indique, j'ai un formulaire réactif contenant plusieurs <mat-select>
. Lors du chargement initial du formulaire, l'option initiale ne s'affiche pas même si form.value
l'indique.
Composants pertinents:
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 pertinent:
<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>
Lorsque le formulaire est chargé, les sélections n'affichent pas l'option initialement sélectionnée. Cependant, elles sont correctement définies, apparemment:
Form value { ... "JobType": "0 - Standard", ... }
Tout ce qui s'affiche sur le formulaire est l'espace réservé.
Cela semble ne pas être si difficile.
Qu'est-ce que je fais mal?
MODIFIER:
this.jobTypes
est chargé lorsque le module est chargé et il s'agit d'un BehaviorSubject qui réside dans mon service de données. J'y souscris dans le constructeur de ce composant ainsi:
this.data.jobTypes.subscribe(jobTypes => { this.jobTypes = jobTypes });
Quelques choses
[formControlName]
must doit être utilisé avec [formGroup]
. Si vous ne souhaitez pas utiliser [formControlName]
+ [formGroup]
, vous pouvez utiliser [formControl]
à la place.
En mode angulaire, il existe une différence entre spécifier un attribut sous la forme value
et [value]
. Lorsqu'un attribut est placé entre crochets []
, il est interprété comme javascript / script de modèle angulaire (identique à {{}}
, je pense). Quand il est pas / entre crochets, il est interprété comme une chaîne (par exemple, value="jobType.value"
=== [value]="'jobType.value'"
et [value]="jobType.value"
=== value="{{jobType.value}}"
(en fait, je pense qu’il existe de subtiles différences entre [value]="jobType.value"
et value="{{jobType.value}}"
, mais w/e)) . Ainsi, lorsque vous écrivez <mat-option *ngFor="let jobType of jobTypes" value="jobType.value">
, la valeur de chaque mat-option
est "jobType.value"
qui, je suppose, ne veut pas de vous. Donc, vous devez changer le code en <mat-option *ngFor="let jobType of jobTypes" [value]="jobType.value">
par exemple.
<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>
Quelque chose de non lié à votre problème, pourquoi avoir à la fois les méthodes createForm()
et initializeForm()
? Pourquoi pas simplement
constructor(private fb: FormBuilder) {
...
// Construct forms
this.createForm();
}
createForm() {
this.editJobInfoForm = this.fb.group({
...
JobType: this.jobTypes[this.currentJobData.JobType].DisplayDesc,
...
});
}
Utilisez comparer avec la fonction telle quelle ...
Étape 1: mettre la balise [compareWith] telle qu'elle est affichée
<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>
Stet 2: déclarer la variable compareFn
et la fonction compareByValue
comme indiqué ci-dessous, aucune modification requise
compareFn: ((f1: any, f2: any) => boolean) | null = this.compareByValue;
compareByValue(f1: any, f2: any) {
return f1 && f2 && f1.name === f2.name;
}