【发布时间】:2021-04-19 19:18:16
【问题描述】:
我正在制作如下表格
我的代码
nested-form.component.ts
public nestedForm: FormGroup;
constructor(
private formBuilder: FormBuilder) {
this.calibrationForm = this.buildFormGroup(formBuilder);
}
buildFormGroup(formBuilder: FormBuilder): FormGroup {
return new FormGroup({
motor: new FormControl('', Validators.required),
properties: new FormControl(""),
});
}
save() {
console.log(this.nestedForm.value);
}
nested-form.component.html
<form [formGroup]="nestedForm" >
<mat-select class="field-select" [(ngModel)]="_selectedMotor"
(selectionChange)="selectMotor($event.value)" formControlName="motor">
<mat-option class="select-option" *ngFor="let item of motors" [value]="item">
item</b>
</mat-option>
</mat-select>
<app-properties formControlName="properties" [type] = "_selectedMotor"></app-properties>
...
</form>
properties.component.ts
@Component({
...
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => PropertiesComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => PropertiesComponent),
multi: true
}
]
})
export class PropertiesComponent implements OnInit, ControlValueAccessor {
@Input() type: string = null;
public propertiesForm: FormGroup;
ngOnInit(): void {
this.propertiesForm = this.buildFormGroup(this.formBuilder);
}
ngOnChanges(changes): void {
this.propertiesForm = this.buildFormGroup(this.formBuilder);
}
buildFormGroup(formBuilder: FormBuilder): FormGroup {
switch (this.type) {
case "OLD":
return new FormGroup(
{
tilt: new FormControl(0, [Validators.required]),
fine_tilt: new FormControl(0, [Validators.required]),
rotate: new FormControl(0, [Validators.required]),
fine_rotate: new FormControl(0, [Validators.required])
});
case "VINTEN":
return new FormGroup(
{
vinten_tilt: new FormControl(0, [Validators.required]),
vinten_rotate: new FormControl(0, [Validators.required])
});
}
}
public onTouched: () => void = () => { };
writeValue(val: any): void {
val && this.propertiesForm.setValue(val, { emitEvent: false });
}
registerOnChange(fn: any): void {
this.propertiesForm.valueChanges.subscribe(fn);
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
setDisabledState?(isDisabled: boolean): void {
isDisabled ? this.propertiesForm.disable() : this.propertiesForm.enable();
}
validate(c: AbstractControl): ValidationErrors | null {
return this.propertiesForm.valid ? null : { invalidForm: { valid: false, message: "propertiesForm fields are invalid" } };
}
...
}
properties.component.html
<form *ngIf="type" class="col" [formGroup]="propertiesForm" [ngSwitch]="type">
<div *ngSwitchCase="OLD">
<input type="number" class="field-input" id="rotate" formControlName="rotate" />
<input type="number" class="field-input" id="fine_rotate" formControlName="fine_rotate" />
<input type="number" class="field-input" id="tilt" formControlName="tilt" />
<input type="number" class="field-input" id="fine_tilt" formControlName="fine_tilt" />
</div>
<div *ngSwitchCase="VINTEN">
<input type="number" class="field-input" id="rotate" formControlName="vinten_rotate" />
<input type="number" class="field-input" id="tilt" formControlName="vinten_tilt" />
</div>
</form>
结果:
假设加载表单时,OLD 是默认值。
我输入了所有字段并单击 OLD 的保存按钮,表单值按预期正确收集。
但是,当我从 OLD 切换到 VINTEN 时,表单 UI 已更新,但保存按钮的有效/无效状态不再起作用,并且单击保存按钮后,表单值仍然是 OLD 属性值,而不是 VINTEN属性值。
我是否遗漏了什么或做错了什么?任何建议表示赞赏。
【问题讨论】:
-
我没有在 ControlValueAccessor 接口的 Properties 组件实现中看到。拥有它后,您可以向父控件发出更改
-
是的,我为 ControlValueAccessor 实现了所有必需的。我没有将它们包含在示例代码中,以保持代码简短,只是主要代码。
-
仅供参考:为了实现 ControlValueAccessor,我关注了这篇文章:medium.com/angular-in-depth/…
-
您能否将问题复制到 StackBlitz 应用程序或类似的应用程序中?
标签: angular typescript forms angular-reactive-forms