在Angular版本4中如何使用ngModel与Formarray选择对象
我已经成功设置了一个Formarray,它有两个控件。这些控件在HTML表单中设置为选择对象。我可以成功推送和显示多个元素集,但是当我尝试更改Formarray的第一个元素中的select对象的值时,其他Formarray元素选择对象的值相同。我正在使用[(ngModel)]将值绑定到对象,我相信这就是为什么值总是相同的原因。我尝试使用[(ngModel)] = stringArray [i]使用Formarray索引的数组变量,但是当页面加载时出现错误。在Angular版本4中如何使用ngModel与Formarray选择对象
任何人都可以建议如何使用[(ngModel)]或其他机制来获取选择对象的值吗?我正在使用ng-lightning选择组件(版本1.3.0)和SLDS Lightning Design CSS。我正在使用Angular版本4.1.3。在我的应用程序的其他部分,我需要使用[(ngModel)]和一个字符串来获取选择对象的值。选择值是一个对象数组,而不是像字符串这样的基本变量。该组件没有定义onSelect()函数。
HTML:
<form [formGroup]="callFlowForm">
<div formArrayName="callDevices">
<!-- Check the correct way to iterate your form array -->
<div *ngFor="let callDevice of callFlowForm.controls.callDevices.controls; let i=index" [formGroupName]="i">
<div class="form-group">
<div class="slds-form-element slds-size--8-of-8">
<ngl-form-element label="Device #: {{ i + 1 }}" class="slds-m-top--small">
<select nglFormControl class="slds-select"
formControlName="callAsset"
[(ngModel)]="selectedDevice"
ngDefaultControl >
<option *ngFor="let device of devices"
[value]="device.id">{{device.assetName}}
</option>
</select>
</ngl-form-element>
</div>
</div>
<div class="form-group">
<div class="slds-form-element slds-size--8-of-8">
<ngl-form-element label="Protocol:" class="slds-m-top--small">
<select nglFormControl class="slds-select"
formControlName="assetTransport"
[(ngModel)]="selectedTransport"
ngDefaultControl >
<option *ngFor="let protocol of transports"
[value]="protocol.id">{{protocol.type}}
</option>
</select>
</ngl-form-element>
</div>
</div>
<button *ngIf="callFlowForm.controls.callDevices.controls.length > 1" (click)="deleteDevice(i)" class="btn btn-danger">Delete Button</button>
</div>
</div>
<button type="button" (click)="addDevice()" class="btn btn-primary">Add Device</button>
</form>
组件:
selectedTransport: string;
selectedDevice: string;
public callFlowForm: FormGroup;
transports: SipTransport[] = [{'id': 1, 'type': 'UDP'},
{'id': 2, 'type': 'TCP'},
{'id': 3, 'type': 'TLS'}
];
devices: Asset[] = [{'id': 1, 'assetName': 'VCS', 'type': 'SIP Registrar'},
{'id': 1, 'assetName': 'CUCM', 'type': 'Call Control'},
{'id': 1, 'assetName': 'SBC', 'type': 'Call Control'},
{'id': 1, 'assetName': 'EX60', 'type': 'Endpoint'}
];
constructor(private dialService: DialService,
private formBuilder: FormBuilder
) { }
ngOnInit() {
this.selectedDevice = '1';
this.selectedTransport = '1';
this.callFlowForm = this.formBuilder.group({
callDevices: this.formBuilder.array([this.addDevices()]) // here
});
}
addDevices() {
return this.formBuilder.group({
callAsset: [''],
assetTransport: ['']
});
}
addDevice() {
const control = <FormArray>this.callFlowForm.controls['callDevices'];
control.push(this.addDevices());
}
deleteDevice(index: number) {
const control = <FormArray>this.callFlowForm.controls['callDevices'];
control.removeAt(index);
}
你为什么不这样做呢?
组件类:
selectedDevice: Asset;
HTML代码:
<select nglFormControl class="slds-select"
formControlName="callAsset"
[(ngModel)]="selectedDevice"
ngDefaultControl >
<option *ngFor="let device of devices"
[value]="device">{{device.assetName}}
</option>
</select>`
你的建议没有奏效。任何版本的ngModel似乎只将选择的对象绑定在一起。删除ngModel似乎是正确的路径,我只需要弄清楚如何迭代现在的formarray值。谢谢。 –
谢谢@ AJT_82谁帮我弄朝着正确的方向发展。这个问题可能不是最好的答案,因为你的答案是不要在formarray中使用ngModel。您需要通过表单控件设置和检索值。当互联网上的例子试图解释“模板驱动”与“模型驱动”或“反应性”形式之间的区别时,这使我感到困惑。他们似乎总是一样的。
这就是HTML应该是怎样的。
HTML:
<select nglFormControl class="slds-select"
formControlName="callAsset"
ngDefaultControl >
<option *ngFor="let device of devices"
[value]="device.id">{{device.assetName}}
</option>
</select>
在我的应用我使用数组值通过较大的集合搜索。当我想要得到的表单值我实现这个:
组件:
const formValue1 = this.callFlowForm.value;
// this allows me to iterate through all devices in the formarray
// and push those values into a list for sorting and further processing
formValue1.callDevices.forEach((element: any) => {
allDevices.push(element.callDevice);
});
不在此例,但在另一种形式,我需要设置窗体控件的值。我使用form.setValue({}),您需要设置所有表单控件的值。然后,如果您只需编辑一个值,则可以使用form.patchValue({})。另一种形式的一个例子是这样的。
的setValue:
this.dialForm.setValue({
id: this.editDialplan.id,
number: this.editDialplan.number,
domainid: this.editDialplan.domainid.id
});
patchValue:
this.dialForm.patchValue({
number: this.editDialplan.number,
});
你是绝对正确的,这是因为ngModel的。双向结合在反应形式中极不鼓励。我无法理解为什么你需要双向绑定。为什么不使用formcontrol来代替。这就是应该使用:) – Alex
嗨@ AJT_82,我不需要ngModel,但我已经在其他形式使用它,特别是在编辑形式,我想预先填充字段与当前值编辑。您的建议可以正常工作,因为我可以在不使用ngModel的情况下对所选的值进行console.log。我只需要弄清楚如何在提交时迭代组件中的formarray数据。我在控制台中得到了这个:这是我的表单{“callDevices”:[{“callAsset”:“24”,“assetTransport”:“2”},{“callAsset”:“34”,“assetTransport”:“1 “}]} –
您也可以使用表单控件设置预选值,或者在设置值之前不建立表单。或者,当你收到它们时,通过修补值的形式,如果这是异步的。但关于你的问题...... *我只需要弄清楚如何在提交时迭代组件中的formarray数据*为什么你需要迭代它?我的意思是你想在迭代中完成什么?作为一个侧面说明它就像迭代任何数组:) – Alex