我想定义一个由FormControls和FormGroups组成的表单。
但如果添加optionalInputGroup:
,我会收到以下错误TypeError:this.form._updateTreeValidity不是函数 在FormGroupDirective._updateDomValue(http://localhost:8100/build/main.js:30206:19) 在FormGroupDirective.ngOnChanges(http://localhost:8100/build/main.js:30065:18) 在Wrapper_FormGroupDirective.ngDoCheck(/ReForFormsModule/FormGroupDirective/wrapper.ngfactory.js:30:18) at CompiledTemplate.proxyViewClass.View_ConfiguratorOptionalGroupInputComponent0.detectChangesInternal(/AppModule/ConfiguratorOptionalGroupInputComponent/component.ngfactory.js:397:32) 在CompiledTemplate.proxyViewClass.AppView.detectChanges(http://localhost:8100/build/main.js:134498:14) 在CompiledTemplate.proxyViewClass.DebugAppView.detectChanges(http://localhost:8100/build/main.js:134693:44) 在CompiledTemplate.proxyViewClass.AppView.internalDetectChanges(http://localhost:8100/build/main.js:134483:18) 在View_ConfiguratorPage5.detectChangesInternal(/AppModule/ConfiguratorPage/component.ngfactory.js:245:19) 在View_ConfiguratorPage5.AppView.detectChanges(http://localhost:8100/build/main.js:134498:14) 在View_ConfiguratorPage5.DebugAppView.detectChanges(http://localhost:8100/build/main.js:134693:44) 在ViewContainer.detectChangesInNestedViews(http://localhost:8100/build/main.js:134830:37) 在View_ConfiguratorPage1.detectChangesInternal(/AppModule/ConfiguratorPage/component.ngfactory.js:369:14) 在View_ConfiguratorPage1.AppView.detectChanges(http://localhost:8100/build/main.js:134498:14) 在View_ConfiguratorPage1.DebugAppView.detectChanges(http://localhost:8100/build/main.js:134693:44) 在ViewContainer.detectChangesInNestedViews(http://localhost:8100/build/main.js:134830:37)
我使用以下方法创建FormConfig:
flattenConfigForForm(inputs: [AbstractConfiguratorControl], returnObject = {}): Object {
inputs.map(input => {
switch (input.type) {
case ConfigurationInputType.Group:
let groupInput: ConfiguratorInputGroup = <ConfiguratorInputGroup> input;
returnObject[groupInput.key] = groupInput;
break;
default:
let basicInput: ConfiguratorInput = <ConfiguratorInput> input;
returnObject[basicInput.key] = basicInput;
returnObject[basicInput.key + ".ion"] = basicInput.value;
}
});
return returnObject;
}
其中ConfigurationInputType.Group是FormGroup的一个实例,带有inputs
- 属性本身包含FormControls,default
是FormControl的一个实例。
这是我在html中构建表单的方式,其中values是由flattenConfigForForm创建的FormGroup。
<form [formGroup]="values" (ngSubmit)="logForm()">
<div class="requiredInputs">
<div *ngFor="let input of config.inputs">
<configurator-number-input [passedFormGroup]="values" *ngIf="isEqualType(input.type,configInputType.Number)"
formControlName="{{input.key}}"></configurator-number-input>
<configurator-toggle-input [passedFormGroup]="values" *ngIf="isEqualType(input.type,configInputType.Toggle)"
formControlName="{{input.key}}"></configurator-toggle-input>
<configurator-select-input [passedFormGroup]="values" *ngIf="isEqualType(input.type,configInputType.Select)"
formControlName="{{input.key}}"></configurator-select-input>
<configurator-optional-group-input formGroupName="{{input.key}}" [passedFormGroup]="input"
formControlName="{{input.key}}"
*ngIf="isEqualType(input.type,configInputType.Group)"></configurator-optional-group-input>
</div>
</div>
</form>
这是我的formGroupInputComponent.html
<div [formGroup]="passedFormGroup">
<ion-input>
<ion-checkbox [(ngModel)]="input.enabled"></ion-checkbox>
</ion-input>
<div *ngFor="let subinput of input.inputs">
<configurator-number-input [passedFormGroup]="input" *ngIf="isEqualType(subinput.type,configInputType.Number)"
formControlName="{{subinput.key}}"></configurator-number-input>
<configurator-toggle-input [passedFormGroup]="input" *ngIf="isEqualType(subinput.type,configInputType.Toggle)"
formControlName="{{subinput.key}}"></configurator-toggle-input>
<configurator-select-input [passedFormGroup]="input" *ngIf="isEqualType(subinput.type,configInputType.Select)"
formControlName="{{subinput.key}}"></configurator-select-input>
</div>
</div>
这是我的formGroupInput.ts
@Component({
selector: 'configurator-optional-group-input',
templateUrl: 'configurator-optional-group-input.html',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ConfiguratorOptionalGroupInputComponent),
multi: true,
}
]
})
export class ConfiguratorOptionalGroupInputComponent implements ControlValueAccessor {
input: ConfiguratorInputGroup;
@Input() public passedFormGroup: FormGroup;
// the method set in registerOnChange, it is just
// a placeholder for a method that takes one parameter,
// we use it to emit changes back to the form
private propagateChange = (_: any) => {
};
constructor() {
}
//ControlValueAccessor
writeValue(obj: any): void {
if (obj) {
console.log(this.passedFormGroup);
this.input = <ConfiguratorInputGroup> obj;
}
}
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
// not used, used for touch input
registerOnTouched(fn: any): void {
}
}
提前致谢!