是否可以在Angular2中将FormGroups嵌套在彼此中?

时间:2017-03-20 07:55:25

标签: javascript angular angular2-forms

我想定义一个由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 {
  }
}

提前致谢!

0 个答案:

没有答案