2017-03-26 1 views
1

J'utilise Angular 2 ReactiveForms pour créer un formulaire. Le formulaire se compose d'un modèle, questions & réponses. Un modèle contient de nombreuses questions et les questions contiennent de nombreuses réponses.Angulaire 2 - Accès aux formulaires imbriqués (FormBuilder)

ngOnInit() { 
    // initialize template 
    this.myForm = this.formBuilder.group({ 
     title: ['', [Validators.required, Validators.minLength(5), Validators.maxLength(30)]], 
     owner: [localStorage.getItem('user')], 
     questions: this.formBuilder.array([ 
      this.initQuestion() 
     ]) 
    }); 
} 

initQuestion() { 
    // initialize question 
    return this.formBuilder.group({ 
     questionText: [{value: '', disabled: true}], 
     answers: this.formBuilder.array([ 
      this.initAnswer() 
     ]) 
    }); 
} 

initAnswer() { 
    // initialize answer 
    return this.formBuilder.group({ 
     answerText: [{value: '', disabled: true}] 
    }); 
} 

addQuestion() { 
    const control = <FormArray>this.myForm.controls['questions']; 
    console.log(control); 
    control.push(this.initQuestion()); 
} 

addAnswer() { 
    const control = <FormArray>this.myForm.get(['questions.0.answers']); 
    control.push(this.initAnswer()); 
} 

Mon but est de permettre à l'utilisateur d'ajouter des questions au modèle, et les réponses à chaque question. Mon problème est cependant que j'ai du mal à accéder au tableau imbriqué appelé "réponses". A partir de maintenant, je peux ajouter des questions et ça marche bien, mais au moment où j'essaie d'ajouter des réponses aux questions (la méthode addAnswer()), j'obtiens une erreur qui dit "Impossible de lire la propriété 'push' de null" , qui référence le control.push dans la méthode addAnswer(). Toute aide est appréciée!

Edit: a oublié d'ajouter mon code HTML:

<table class=pageTable align=center border="1px"> 
 
    <form [formGroup]="myForm" novalidate (ngSubmit)="save(myForm)" align=center> 
 
     <!-- we will place our fields here --> 
 
     <input type="submit" [disabled]="!myForm.valid" value="Submit Template"> 
 

 
     <!-- Template Title --> 
 
     <div class="form-group"> 
 
      <label>Template Title:</label><br/> 
 
      <input type="text" formControlName="title"><br/> 
 
      <!--display error message if name is not valid--> 
 
      <small *ngIf="!myForm.controls.title.valid" class="text-danger"> 
 
       Title must be between 5-30 characters. 
 
      </small> 
 
     </div> 
 

 
     <br/> 
 

 
     <!-- List of Questions --> 
 
     <div formArrayName="questions" align=center> 
 
      <div [formGroupName]="i" *ngFor="let question of myForm.controls.questions.controls; let i=index" class="Question-panel"> 
 
       <div class="Question-panel-title"> 
 
        <span>Question {{i + 1}}:</span> 
 
        <!-- show remove button when more than one address available --> 
 
        <span *ngIf="myForm.controls.questions.controls.length > 1" 
 
         (click)="removeQuestion(i)"> 
 
        </span> 
 
        <question [group]="myForm.controls.questions.controls[i]"></question> 
 
       </div> 
 

 
       <!-- Llist of Answers --> 
 
       <div formArrayName="answers" align=center> 
 
        <div [formGroupName]="j" *ngFor="let answer of question.controls.answers.controls; let j=index"> 
 
         <div class="Question-panel-content"> 
 
          <span>Answer {{j + 1}}:</span> 
 
          <br/><a (click)="addAnswer()" style="cursor: default"> 
 
           Add answer 
 
          </a> 
 
         </div> 
 
        </div> 
 
       </div> 
 
      </div> 
 
     </div> 
 

 
     <br/> 
 

 
     <a (click)="addQuestion()" style="cursor: default"> 
 
      Add question 
 
     </a> 
 
    </form> 
 
</table>

Répondre

1

Je pense que vous devriez utiliser la chaîne

this.myForm.get('questions.0.answers') 

ou tableau comme

this.myForm.get(['questions', 0, 'answers']); 

Mise à jour

Selon votre code html

addAnswer(idx: number) { 
    const control = <FormArray>this.myForm.get(['questions', idx, 'answers']); 
    control.push(this.initAnswer()); 
} 

et en html

<a (click)="addAnswer(i)">Add answer</a> 

Voir aussi

+0

Merci pour votre solution, cela me conduit sur le bon chemin. this.myForm.get ('questions.0.answers') fonctionne presque comme prévu, mais savez-vous peut-être un moyen d'ajouter une réponse à la question respective? Parce que peu importe à quelle question je décide d'ajouter une réponse, seule la première question reçoit une nouvelle réponse, d'où la "question.0.answers". Je viens d'ajouter mon HTML sur le post :) – SquishyAura

+0

Vous mon bon monsieur sont un sauveur. Merci beaucoup et passez une merveilleuse journée! – SquishyAura