J'ai deux tableaux de données: AssociatedPrincipals (données précédemment enregistrées) et ReferencePrincipals (données statiques à remplir dans les contrôles déroulants). Je ne parviens pas à afficher/sélectionner la valeur précédente de AssociatedPrincipals dans un montant dynamique (la plupart des exemples utilisent un seul menu déroulant) de menus déroulants au chargement de la page.
Je ne suis pas sûr de savoir comment configurer le formulaire (code behind et HTML), en particulier pour définir le formControlName de Select. Actuellement, les valeurs statiques de chaque liste déroulante sont remplies, mais je ne parviens pas à associer correctement la valeur sélectionnée.
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>
J'apprécie vos commentaires!
EDIT: Ajouté Plunker montrant le problème:https://embed.plnkr.co/XMLvFUbuc32EStLylDGO/
Selon la démonstration que vous avez fournie, plusieurs problèmes sont énumérés ci-dessous:
formControlName
n'est pas affecté à select
. Puisque vous parcourez associatedPrincipals
pour afficher la liste déroulante de manière dynamique. Et associatedPrincipals
qui est un formArray qui peut être considéré comme ci-dessous:
associatedPrincipals = {
"0": FormControl,
"1": FormControl
}
Donc, vous pouvez simplement assigner i
qui est défini à *ngFor
expression à formControlName
.
<select formControlName="{{i}}" style="margin-top: 10px">
...
</select>
Tout en liant object à option
, Angular comparera la valeur par défaut et la valeur de option
par object instance par défaut.
Vous pouvez définir la même instance (obtenir de la valeur de __Controls de referencePrincipals
) pour formControl de associatedPrincipals
(en tant que réponse de @Fetra R.). Mais ce n’est pas le moyen le plus pratique, car il faut prendre une certaine logique pour conserver la même instance d’un objet.
Ici, je vous donnerais une autre solution qui utilise la directive compareWith
spécialement conçue pour votre situation actuelle, voir docs.
En utilisant la directive compareWith
, il vous suffit de mettre en œuvre une compareFun
pour indiquer à Angular comment considérer deux objets (avec des instances différentes) identiques. Ici, vous pouvez inclure comparing object instance
et comparing object fields
en même temps.
<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;
}
Vous devez passer exactement la même référence de l'objet qui a renseigné la sélection dans celui sélectionné pour obtenir la valeur sélectionnée.
Ici, vous utilisez une valeur de FormControl
dans referencePrincipals
pour renseigner votre selectbox
. Pour l'obtenir sélectionné, utilisez cet objet:
public createPrincipalFormControl(principal) {
const selectedFormControl = this.referencePrincipals.controls.find(form => form.value.code === principal.code)
return this.formbuilder.control(selectedFormControl.value);
}
Plunker de travail. https://plnkr.co/edit/vw3WZ6?p=preview