带有级联形式数组的角度6反应形式

时间:2019-03-15 18:50:21

标签: angular typescript angular-reactive-forms

我正在训练有角反应性形式,并且正在建立一个界面,其作用是提供常见问题解答。表单的第一层将是主题,第二层是问题,第三层是后续步骤。

尽管第二个级别与第一个级别相同,但第三个级别却使我感到痛苦。终端输出controls.registerOnChange is not a functionCannot find control with path: 'questions -> steps'

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

我的component.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)
  }



}

我的component.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>

预先感谢您帮助我取得进步。

1 个答案:

答案 0 :(得分:0)

似乎在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它正在处理哪个问题。