Не удается найти элемент управления с именем: - PullRequest
0 голосов
/ 30 января 2019

У меня довольно сложная форма, которую я хочу разбить на отдельные компоненты.Вот моя базовая форма (только взятые примеры полей), я использую FormBuilder:

ngOnInit() {
  this.predictorQuestion = this.fb.group({
  question: ['', Validators.required],
  options: this.fb.array([
    this.fb.control('', Validators.required),
  ]),
  meta_options: this.fb.group({
   test_type: ['', Validators.required],
  })
});

get meta_options() {
  return this.predictorQuestion.get('meta_options') as FormGroup;
}

get options() {
  return this.predictorQuestion.get('options') as FormArray;
}

Если я попытаюсь подключить это к моим шаблонам, она отлично работает:

<form [formGroup]="predictorQuestion" fxLayout="column">
  <mat-form-field fxFlex appearance="outline">
    <mat-label>Question</mat-label>
    <input matInput formControlName="question">
  </mat-form-field>

  <div fxLayoutAlign="space-between center">
    <h3>Options</h3>
    <button (click)="addOption()" matTooltip="Add option" matTooltipPosition="right" mat-mini-fab type="button">
      <mat-icon>add</mat-icon>
    </button>
  </div>
  <div formArrayName="options" fxLayout="column">
    <div *ngFor="let answer of options.controls; let i = index" fxLayout="row" fxLayoutAlign="space-between stretch">
      <mat-form-field appearance="outline" fxFlex>
        <mat-label>Option {{ i+1 }} </mat-label>
        <input fxFlex matInput [formControlName]="i">
      </mat-form-field>
      <button mat-icon-button matTooltip="Remove this option" matTooltipPosition="right" (click)="removeOption(i)">
        <mat-icon>close</mat-icon>
      </button>
    </div>
  </div>

  <div formGroupName="meta_options" fxLayoutAlign="space-between" fxLayoutGap="20px" fxLayout="column">
    <mat-form-field fxFlex="25">
      <mat-select formControlName="test_type">
        <mat-option *ngFor="let vtype of vtypes" value="{{ vtype.value }}">{{ vtype.name }}</mat-option>
      </mat-select>
    </mat-form-field>
  </div>
</form>

Это отображается без ошибок.

Если я попытаюсь разбить meta_options.test_type в отдельном компоненте таким образом, как:

component.ts

@Input() parent_form: FormGroup;
public vtypes: Array<Object>;


  constructor(private fb: FormBuilder) {
    this.vtypes = [
      {
        name: 'Timestamp',
        value: 'timestamp'
      },
      {
        name: 'Over',
        value: 'over'
      }
    ];
  }

component.html

<mat-form-field fxFlex="25" [formGroup]="parent_form">
  <mat-select formControlName="test_type">
    <mat-option *ngFor="let vtype of vtypes" value="{{ vtype.value }}">{{ vtype.name }}</mat-option>
  </mat-select>
</mat-form-field>

и использование этого компонента в моей основной родительской форме как

<meta-option-value [parent_form]="predictorQuestion"></meta-option-value>

Я получаю следующую ошибку:

"Cannot find the control with the name: 'test_type'"

Что мне здесь не хватает?

Ответы [ 3 ]

0 голосов
/ 05 февраля 2019

Вы передаете полный FormGroup (predictorQuestion) ребенку.Вам нужно только передать predictorQuestion.get('meta_types') на parent_form как [parent_form]="predictorQuestion.get('meta_types')".

0 голосов
/ 05 февраля 2019

Вы можете сказать, что ваш дочерний компонент использует formControlName="test_type" в зависимости от родительского контейнера независимо от типа контейнера (FormGroupName, FormGroup или FormArray), определив viewProviders:

meta-option-value.component.ts

@Component({
  selector: 'meta-option-value',
  template: `
    <mat-form-field fxFlex="25">
      <mat-select formControlName="test_type">
        <mat-option ...>{{ vtype.name }}</mat-option>
      </mat-select>
    </mat-form-field>
  `,
  viewProviders: [{
    provide: ControlContainer,
    useFactory: (container: ControlContainer) => container,
    deps: [[new SkipSelf(), ControlContainer]],
  }]
})
export class MetaOptionValueComponent {
  ...
}

parent.template.html

<div formGroupName="meta_options">
                     /\
                     ||
              will look at this group   
    <meta-option-value></meta-option-value>
</div>

Как видите, MetaOptionValueComponent содержит только свою собственную связанную логику.

Пример Stackblitz

См. Также:

Конечно, другой способ - передать экземпляр FormGroup или FormControl и использовать его напрямую, как предлагается в других ответах

0 голосов
/ 30 января 2019

передайте «контроль» и оставьте [FormControl] в ваших детях

<meta-option-value [formControl]="predictorQuestion.get('meta_options')">
</meta-option-value>

Ваши мета-опции

<mat-form-field fxFlex="25" [formControl]="formControl">
  ...

</mat-form-field>

//and add the Input
@Input()formControl: FormControl;

та же идея сработает, если вам нужно передать FormGroupили массив форм

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...