我需要一些建议才能在我的angular2应用程序中实现一个表单。
我有一个情境对象,其中包含三个重要的东西:id,name,type 在表单中,我创建了一个带有情境名称的下拉列表(我使用服务来获取列表并使用ngFor指令来显示) 根据所选情况的类型,我使用自己的formControls构建一个formGroup(我在下拉列表中使用onChange函数) 我使用类型在模板中显示新输入(许多情况可以具有相同的类型)。 我的模板中有这个代码有问题,当我选择一个值时,所选的值不再出现...
下面是我的代码片段,用以理解我在说什么:
模板:
<form [formGroup]="myForm" (ngSubmit)="saveForm()" novalidate>
<select class="form-control" [(ngModel)]="selectedSituation" (change)="onChangeSituation()" formControlName="name">
<option [ngValue]="situation" *ngFor="let situation of situationsArray">{{situation.name}}</option>
</select>
<div *ngIf="selectedSituation?.type == 1">
<!-- some fields -->
</div>
<div *ngIf="selectedSituation?.type == 2">
<!-- other fields -->
</div>
</form>
组件:
situationsArray: string[];
selectedSituation: any;
type: any;
constructor(
private _fb: FormBuilder
) { }
createDefaultForm(){
this.myForm = this._fb.group({
name: ['', Validators.required]
// inputs not concerning by dropdown list
});
}
createType1Form(){
this.myForm = this._fb.group({
name: ['', Validators.required]
// inputs for type = 1
});
}
createType2Form(){
this.myForm = this._fb.group({
name: ['', Validators.required]
// inputs for type = 2
});
}
ngOnInit(){
this.createDefaultForm(); // a formGroup for the inputs who aren't concerned by the dropdwon list
this.getListSituations(); // a service to get the situations list
}
onChangeSituation(): void{
console.log(this.selectedSituation);
if(this.selectedSituation.type == 1) {
this.createJobForm();
} else
if(this.selectedSituation.type == 2) {
this.createPeForm();
} else
if(this.selectedSituation.type == 3) {
this.createPeaForm();
} else
this.createDefaultForm();
}
您对显示器问题有什么想法吗? 也许我使用了错误的做法......
我现在已经坚持了一段时间,欢迎你的所有建议,谢谢。
答案 0 :(得分:2)
问题:
您在构建表单时重置name
表单控件
您正在使用对象作为select的值。即使您没有遇到上述问题,Angular也无法在不相互引用的情况下匹配对象值。
其次,就像在其他答案中提到的那样,不要混合模板驱动和反应形式,它们真的不能很好地结合在一起。
我要做的是更改选择,例如使用您要查找的type
,然后为条件字段创建子表单组。这样您就可以切换子组,而不需要重建所有常见(如果有的话)字段。所以像...(缩短代码)
createDefaultForm() {
this.myForm = this._fb.group({
name: ['', Validators.required],
// other inputs
subGroup: this._fb.group({})
});
}
您的选择切换子组:
<select class="form-control" (change)="createSubForm()" formControlName="name">
<option [ngValue]="situation.type" *ngFor="let situation of situationsArray">
{{situation.name}}
</option>
然后方法createSubGroup
:
createSubForm() {
if (this.myForm.controls.name.value === 1) {
this.myForm.setControl('subGroup', this.createType1Form())
} else {
this.myForm.setControl('subGroup', this.createType2Form())
}
}
createType1Form() {
return this._fb.group({
name1: ['type1', Validators.required]
// inputs for type = 1
});
}
createType2Form() {
return this._fb.group({
name2: ['type2', Validators.required]
// inputs for type = 2
});
}
StackBlitz展示了这一点: DEMO
答案 1 :(得分:0)
我认为问题是因为它在表单内部。每次构建新表单时,您都会生成一个新选择,但这没有任何价值。尝试移动选择
答案 2 :(得分:0)
您正在将反应驱动的表单构建与模板驱动的表单构建混合在一起。
指令“[(ngModel)]”用于模板驱动的表单。
您需要将模板更改为:
<select class="form-control" formControlName="name">
<option [value]="situation.type" *ngFor="let situation of situationsArray">
{{situation.name}}
</option>
</select>
这会在下拉列表中显示situation.name,当选择一个时,formControl
的值将设置为situation.type
。
在你的ngOnInit:
this.myForm.controls['name'].valueChanges.subscribe(
value => {
console.log(value);
onChangeSituation(value);
}
);
然后将onChangeSituation()更改为:
onChangeSituation(newValue: number): void{
switch(newValue) {
case 1:
this.createJobForm();
break;
case 2:
this.createPeForm();
break;
case 3:
this.createPeaForm();
break;
default:
this.createDefaultForm();
break;
}
}
我假设newValue是一个数字。
修改强>
但是,使用此解决方案,由于您创建了对表单控件的valueChanges的订阅,因此您需要在销毁组件时取消订阅。有几种方法可以实现这一目标。问题描述为here。
建议的解决方案是here。所以我会这样做:
在您的组件中添加一个新变量(主题):
destroy$: Subject<boolean> = new Subject<boolean>();
将订阅行修改为:
this.myForm.controls['name'].valueChanges.takeUntil(this.destroy$).subscribe(
添加ngOnDestroy方法:
ngOnDestroy() {
this.destroy$.next(true);
// Now let's also unsubscribe from the subject itself:
this.destroy$.unsubscribe();
}
并修改组件类的签名以实现它:
export class MyComponent implements OnInit, OnDestroy