嵌套表单数组出现错误:错误错误:找不到路径为“'问题-> 0->代码'的控件”

时间:2020-10-25 02:02:54

标签: angular angular-reactive-forms

我正在寻求帮助

ERROR Error: Cannot find control with path: 'questions -> 0 -> code'
我不断从此代码进入控制台的错误。我咨询了StackOverflow,并进行了一些更改,但错误普遍存在。

我的打字稿文件如下

export class SurveyBuilderPageComponent {
  @Input()
  get survey() {
    return this._survey
  }
  set survey(value: Survey) {
    this._survey = value
    const survey: Survey = value || {
      id: null,
      title: '',
      subtitle: '',
      questions: [
        {
          code: '',
          category: '',
          title: '',
          text: '',
          type: '',
          date: '',
        },
      ],
    }

    this.form = this.formBuilder.group({
      title: [survey.title, Validators.required],
      subtitle: [survey.subtitle, Validators.required],
      questions: this.formBuilder.array(
        survey.questions.map((question) =>
          this.formBuilder.group({
            code: [question.code],
            category: [question.category, Validators.required],
            title: [question.title],
            text: [question.text, Validators.required],
            type: [question.type],
            date: [question.date],
          })
        )
      ),
    })
  }
  @Output() save = new EventEmitter()

  _survey: Survey

  constructor(
    private formBuilder: FormBuilder,
    private surveyService: SurveyService,
    private router: Router
  ) {}

  form: FormGroup

  private newQuestionFormGroup(): FormGroup {
    return this.formBuilder.group({
      title: ['', Validators.required],
      text: ['', Validators.required],
      category: ['', Validators.required],
    })
  }

  submit() {
    if (this.form.valid) {
      this.save.emit(
        this.survey.id
          ? { ...this.form.value, id: this.survey.id }
          : this.form.value
      )
    }
  }
  handleAddNewQuestion() {
    const questions = this.form.get('questions') as FormArray
    this.insertQuestion(questions.controls.length)
  }

  private insertQuestion(index: number) {
    const questions = this.form.get('questions') as FormArray
    questions.insert(index, this.newQuestionFormGroup())
  }

  get questions(): AbstractControl[] {
    return (this.form.get('questions') as FormArray).controls
  }

  handleDeleteQuestion(index: number) {
    const questions = this.form.get('questions') as FormArray
    questions.removeAt(index)
  }

  handleInsertAfterQuestion(event: Event, index: number) {
    event.stopPropagation()
    this.insertQuestion(index + 1)
  }

  handleInsertBeforeQuestion(event: Event, index: number) {
    event.stopPropagation()
    this.insertQuestion(index)
  }
}

我的HTML文件

<div class="container" *ngIf="survey">
  <h2>Survey Details</h2>
  <form [formGroup]="form" (ngSubmit)="submit()">
    <div>
      <mat-form-field class="title-field">
        <input matInput type="text" placeholder="Title" formControlName="title" />
      </mat-form-field>
    </div>
    <div>
      <mat-form-field class="title-field">
        <input matInput type="text" placeholder="Subtitle" formControlName="subtitle" />
      </mat-form-field>
    </div>
    <!--create questions section-->
    <h2>Questions</h2>
    <div class="field-space">
      <!--we should pick a spacing class standard-->

      <ng-container formGroupName="questions">
        <ng-container *ngFor="let question of questions; let idx=index">
          <mat-expansion-panel [formGroupName]="idx" [expanded]="true">
            <mat-expansion-panel-header>
              <mat-panel-title>
                <mat-panel-title class="line-height-40px">
                  <mat-icon class="line-height-40px margin-right-half-em">post_add</mat-icon>
                  Question {{idx+1}}
                  <button mat-icon-button (click)="handleInsertBeforeQuestion($event, idx)">
                    <mat-icon>navigate_before</mat-icon>
                  </button>
                  <button mat-icon-button (click)="handleInsertAfterQuestion($event, idx)">
                    <mat-icon>navigate_next</mat-icon>
                  </button>
                  <button mat-icon-button (click)="handleDeleteQuestion(idx)">
                    <mat-icon>delete</mat-icon>
                  </button>
                </mat-panel-title>
              </mat-panel-title>
            </mat-expansion-panel-header>

            <div class="field-space">
              <mat-form-field class="title-field">
                <input matInput placeholder="Question Code" formControlName="code" />
              </mat-form-field>
            </div>

            <div class="field-space">
              <mat-form-field class="title-field">
                <input matInput formControlName="text" placeholder="Question Text" />
              </mat-form-field>
            </div>
            <div class="field-space">
              <mat-select placeholder="Category" class="question-dropdown" formControlName="category">
                <mat-option value="End Users">End Users</mat-option>
                <mat-option value="Engagement">Engagement</mat-option>
                <mat-option value="Foundations">Foundation</mat-option>
                <mat-option value="Impediments">Impediments</mat-option>
                <mat-option value="Product">Product</mat-option>
                <mat-option value="Scaling">Scaling</mat-option>
                <mat-option value="Team">Team</mat-option>
                <mat-option value="Technical">Technical</mat-option>
              </mat-select>
            </div>
          </mat-expansion-panel>
        </ng-container>
      </ng-container>
    </div>
    <div class="field-space">
      <button mat-button color="secondary" (click)="handleAddNewQuestion()">
        New Question
      </button>
      <button mat-raised-button type="submit" [disabled]="!form.valid" color="primary">
        Submit
      </button>
    </div>
  </form>
</div>

回购位于以下链接中

https://github.com/jbrockSTL/misc/tree/main/survey-builder-page

1 个答案:

答案 0 :(得分:2)

解决这种错误的最简单方法是跟踪错误;

Cannot find control with path: 'questions -> 0 -> code'"

问题-formArray
0-> formGroup
代码-> formControl

您的html结构应反映出这一点 将<ng-container formGroupName="questions">更改为<ng-container formArrayName="questions">

尝试添加新问题时遇到的下一个错误是

Cannot find control with path: 'questions -> 1 -> code'"

注意“ 1”

这意味着表单数组正在运行,唯一的问题是表单控件code

如果您查看自己的newQuestionFormGroup(),则code丢失了

 private newQuestionFormGroup(): FormGroup {
    return this.formBuilder.group({
      title: ["", Validators.required],
      text: ["", Validators.required],
      category: ["", Validators.required]
    });
  }

只需添加code即可使用该功能

See this Solution on Stackblitz 通过上面的操作,现在结构已经满足,代码应该可以工作了