我有两个数据数组: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/
答案 0 :(得分:8)
根据您提供的演示,有以下几个问题:
formControlName
没有分配select
。 由于您循环遍历associatedPrincipals
以动态显示下拉列表。 associatedPrincipals
这是一个 formArray ,可以考虑如下:
associatedPrincipals = {
"0": FormControl,
"1": FormControl
}
因此,您只需将i
表达式定义的*ngFor
分配给formControlName
。
<select formControlName="{{i}}" style="margin-top: 10px">
...
</select>
将对象绑定到option
时,默认情况下,Angular会将默认值和option
的值与对象实例进行比较。
您可以将同一个实例(从referencePrincipals
的formControls的值获取)设置为associatedPrincipals
的formControl(作为@Fetra R。的答案)。但这不是最方便的方法,因为你必须采取一些逻辑来保持对象的同一个实例。
在这里,我将为您提供另一种解决方案,该解决方案使用专为您当前情况设计的compareWith
指令,请参阅 docs 。
使用compareWith
指令,您只需要实现一个compareFun
来告诉angular如何将两个对象(具有不同的实例)视为相同。这里可以包含comparing object instance
和{ {1}}同时。
comparing object fields
答案 1 :(得分:2)
您需要将填充select的对象的完全相同的引用传递给选定的引用以获取所选值。
在这里,您使用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 :(得分:1)
您的方法至少有两个问题。
此处的数据源可能是异步的。这意味着您不应该在this.initiPrincipals(responseData[0])
之后立即执行var responseData
,而是在回调任何方法获取数据或订阅http服务时,如果您通过Observable获取数据。
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)