我想定义一个由FormControls和FormGroups组成的表单 .

但是,如果我添加optionalInputGroup,我会收到以下错误:

TypeError:this.form._updateTreeValidity不是FormGroupDirective.ngOnChanges(http:// localhost:8100 / build /)中FormGroupDirective._updateDomValue(http:// localhost:8100 / build / main.js:30206:19)的函数main.js:30065:18)在CompiledTemplate.proxyViewClass.View_ConfiguratorOptionalGroupInputComponent0.detectChangesInternal(/AppModule/ConfiguratorOptionalGroupInputComponent/component.ngfactory.js:397)的Wrapper_FormGroupDirective.ngDoCheck(/ReactiveFormsModule/FormGroupDirective/wrapper.ngfactory.js:30:18) 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)在View_ConfiguratorPage5.detectChangesInternal(/AppModule/ConfiguratorPage/component.ngfactory.js:245)的CompiledTemplate.proxyViewClass.AppView.internalDetectChanges(http:// localhost:8100 / build / main.js:134483:18) :19)在View_ConfiguratorPage5.AppView.detectCh在ViewContainer.detectChangesInNestedViews中的View_ConfiguratorPage5.DebugAppView.detectChanges(http:// localhost:8100 / build / main.js:134693:44)中的anges(http:// localhost:8100 / build / main.js:134498:14) 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)在ViewContainer.detectChangesInNestedViews(http:// localhost:8100)的View_ConfiguratorPage1.DebugAppView.detectChanges(http:// localhost:8100 / build / main.js:134693:44) /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 -Attribute本身包含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 {
  }
}

提前致谢!