2つのデータ配列があります。AssociatedPrincipals(以前に保存されたデータ)とReferencePrincipals(ドロップダウンコントロールに入力する静的データ)です。ページロード時にドロップダウンの動的な量(ほとんどの例では単一のドロップダウンを使用)で表示/選択されるAssociatedPrincipalsから以前の値を取得するのに苦労しています。
フォーム(コードビハインドとHTML)の設定方法、特にSelectのformControlNameの設定方法がわかりません。現在、各ドロップダウンの静的な値が入力されていますが、選択された値を正しくバインドできません。
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>
フィードバックをありがとう!
編集:問題を示すPlunkerを追加しました:https://embed.plnkr.co/XMLvFUbuc32EStLylDGO/
あなたが提供したデモに基づいて、以下にリストされているようにいくつかの問題があります:
formControlName
に割り当てられているselect
はありません。associatedPrincipals
をループして、ドロップダウンリストを動的に表示しているためです。そしてassociatedPrincipals
はformArrayであり、以下のように考えることができます:
associatedPrincipals = {
"0": FormControl,
"1": FormControl
}
そのため、*ngFor
式で定義されているi
をformControlName
に割り当てるだけです。
<select formControlName="{{i}}" style="margin-top: 10px">
...
</select>
objectをoption
にバインドしている間、Angularはデフォルト値とoption
の値をobject instanceで比較しますデフォルトでは。
同じインスタンス(referencePrincipals
のformControlsの値から取得)をassociatedPrincipals
のformControlに設定できます(@Fetra Rの回答として)。ただし、オブジェクトの同じインスタンスを保持するためにいくつかのロジックを取る必要があるため、これは最も便利な方法ではありません。
ここでは、現在の状況に合わせて特別に設計されたcompareWith
ディレクティブを使用する別のソリューションを紹介します。docsを参照してください。
compareWith
ディレクティブを使用すると、compareFun
を実装してangular 2つのオブジェクト(インスタンスが異なる)を同じものと見なす方法を伝える必要があります。ここでcomparing object instance
とcomparing object fields
を同時に含めます。
<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;
}
選択した値を取得するには、選択したオブジェクトに選択を移入するオブジェクトとまったく同じ参照を渡す必要があります。
ここでは、FormControl
のすべてのreferencePrincipals
の値を使用してselectbox
に入力します。そのため、このオブジェクトを選択して選択します。
public createPrincipalFormControl(principal) {
const selectedFormControl = this.referencePrincipals.controls.find(form => form.value.code === principal.code)
return this.formbuilder.control(selectedFormControl.value);
}
アプローチには少なくとも2つの問題があります。
ここのデータソースはおそらく非同期です。つまり、_var responseData
_の直後にthis.initiPrincipals(responseData[0])
を実行するのではなく、Observableを介してデータを取得する場合は、データを取得するメソッドのコールバックまたはhttpサービスのサブスクリプションで実行する必要があります。
_let subscription = myservice.getmedata.subscribe(data => { //here you should do your initializations with data from server };
_
データが@Input()からのものである場合、正しい表現はngOnChanges
です。
Fetraが指摘したように、以前に選択したオプションは、選択リストに事前に入力したものとまったく同じ値であるという事実に関係なく、選択済みとして設定するには、入力したオプションを正確に参照する必要があります。だから、次のようなもの:
this.formGroup.controls['yourSelectControl'].patchValue(this.yourInitialCollectionOfOptions.find(v => v.propertyByWhichYouWantToCompare == valueFromServer.propertyByWhichYouWantToCompare)