首页 > 解决方案 > 具有级联formarrays的角度6反应形式

问题描述

我正在使用角度反应形式进行培训,并且正在构建一个界面,其作用是提供常见问题解答。表格的第一层是主题,第二层是问题,第三层是要遵循的一些步骤。

虽然第二级和第一级没问题,但第三级让我很痛苦。终端输出controls.registerOnChange is not a functionCannot find control with path: 'questions -> steps'

我想了解我在哪里以及为什么会犯错误。

我的组件.ts

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms'
import { ThemeService } from 'src/app/service/theme.service';

@Component({
  selector: 'app-edition-form',
  templateUrl: './edition-form.component.html',
  styleUrls: ['./edition-form.component.css']
})
export class EditionFormComponent implements OnInit {

  constructor(private fb:FormBuilder, private ts:ThemeService) { }
  form:FormGroup;
  themes;
  s_theme;
  questions;
  s_question;
  steps;
  s_step;
  msg;
  hitButton:string;

  ngOnInit() {
    this.s_theme==0;
    this.s_question=null;
    this.s_step=null;
    this.ts.getThemesList().subscribe(
      data => this.themes = data,
      err => this.msg = err
    )
    this.form = this.fb.group({
      id:'',
      libelle:'',
      //questions: this.fb.array([this.fb.control('')])
      questions: this.fb.array([this.initQuestion()])
    })

  }

  initQuestion(){
    return this.fb.group({
      id:'', libelle:'', steps: this.fb.array([this.initStep()])
    })
  }

  initStep(){
    return this.fb.group({
      id:'', libelle:'', path:''
    })
  }

  validateForm(){

  }


  // Définition d'un getter pour récupérer le tableau qu'on souhaite construire dans le formulaire
  get questionList(){
    return this.form.get('questions') as FormArray
  }

  get stepsList(){
    return this.form.get('questions').get('steps') as FormArray
  }

  // ajouter des contrôles dans les éléments de ce tableau
  addQuestion(){
    this.questionList.push(this.fb.control(''))
  }



  // sélection dans les listes déroulantes
  setTheme(theme){
    if(theme.libelle==null){
      this.s_theme = null;
      this.questions = null;
      this.removeControls(this.questionList)
    }else{
      this.s_theme = theme.id
    this.ts.getQuestions(theme.id).subscribe(
      data=> {
        this.questions = data
        this.removeControls(this.questionList)
        this.questions.forEach(element => {
          this.questionList.push(this.fb.control(element.libelle)) //permet de publier la liste des questions dans le formulaire
        });
      },
      err => this.msg = err
    )
    }
  }

  removeControls(list:FormArray){
    while(list.controls.length!==0){ //permet de supprimer des controles
      list.removeAt(0)
    }
  }

  setQuestion(question){
    this.s_question = question.id
    this.ts.getSteps(this.s_theme, question.id).subscribe(
      data => {
        this.steps = data

      },
      err=>this.msg=err
    )
    console.log(question)
  }

  setStep(step){
    this.s_step = step.id;
  }

  handleSubmit(formData){
    console.log(formData)
  }

  button(number){
    this.hitButton = number;
    if(this.hitButton=="01"){

    }else if(this.hitButton =="02"){
      this.addQuestion()
    }
    console.log(this.hitButton)
  }



}

我的组件.html

<form [formGroup]=form (submit)=handleSubmit(this.form.value)>
  <div>
    <app-dropdown label="Thème" [list]="this.themes" (selection)="setTheme($event)"></app-dropdown>
  </div>
  <div *ngIf="this.s_theme==null">
    <p>ou</p>
    <input type="text" placeholder="Saisir nouveau thème" class="form-control" formControlName="libelle" />
  </div>

  <hr>
  <app-dropdown label="Questions" [list]="this.questions" (selection)="setQuestion($event)"></app-dropdown>
  <div>
    <div class="d-flex align-items-center">
      <div class="col-1">
        Ou
      </div>
      <div class="col-8">
        <app-bouton class="" id=02 text="Ajouter une question" (hit)=button($event)></app-bouton>
      </div>
    </div>
    <div formArrayName="questions">
      <div *ngFor="let question of questionList.controls; let i=index">
        <div class="row">
          <div class="col-1">
            <p>{{i+1}}</p>
          </div>
          <div class="col-8">
            <input type="text" class="form-control" placeholder="Saisissez votre question" [formControlName]="i" />
            <div formArrayName="steps">
              <div *ngFor="let step of questionList['controls'].steps['controls']; let j=index">
                <input type="text" class="form-control" placeholder="Saisissez votre étape" [formControlName]="j"/>
              </div>
            </div>

          </div>
        </div>
      </div>
      <hr>

    </div>
  </div>
  <hr>
  <button type="submit">Enregistrer</button>
</form>

提前感谢您帮助我进步。

标签: angulartypescriptangular-reactive-forms

解决方案


似乎steps正在直接搜索questions而不是实际搜索。

你可以尝试这样的事情:

 <ng-container  [formGroup]="form.questions.get(i)">
                <div formArrayName="steps">
                <div *ngFor="let step of questionList['controls'].steps['controls']; let j=index">
                    <input type="text" class="form-control" placeholder="Saisissez votre étape" [formControlName]="j"/>
                </div>
                </div>
            </ng-container>

我不太确定语法,但我的想法是告诉 Angular 它正在处理哪个问题。


推荐阅读