2017-07-21 4 views
0

Ich habe versucht, dies für eine Weile, um herauszufinden, und ich bin fest. Mein Ansatz scheint ineffizient und inkorrekt zu sein.ReactiveForm mit NgFor

Was I tue, Erzeugung meine Form Werte mit * ngFor, ich schaffe dynamisch Formular-Steuerelemente für Antwort ist ebenso wie Fragen.

Das Problem ist, dass auf Submit Ich brauche die Antworten mit den Fragen zugeordnet, so dass ich zum nächsten Bildschirm passieren kann. Die aus * ngFor generierten Fragen sind nach Kontrollkästchen ausgewählt, wenn das ausgewählte = true; dann Blase die Frage an die Spitze.

Das Problem ist, dass auf einreichen, pvqForm die formControls vergangen, ich brauche die Antwort mit der Frage assoziieren sie mit verbunden war. FormControls haben ein Präfix {{i}} -> index, dieser Index ist jedoch nach der Sortierung. Also darf der Index 19 nicht question_id = '19' sein.

Das Objekt Ich versuche onSubmit zu erreichen ist:

{ 
    question_id: "#", 
    EN: "Question - #", 
    FR: "Question - #", 
    answer: "", 
    isSelected: true 
} 

Ich kann alle Fragen innerhalb eines Arrays speichern und verwenden Sie einfach question_id die Fragen entsprechen. Wie kann ich jedoch die passende Frage-ID zusammen mit der Antwort zusammen erreichen?

Das Objekt, das die * ngFor ist in der Form ...

{ 
    question_id: "1", 
    EN: "Question 1 - EN", 
    FR: "Question 1 - FR", 
    isSelected: true 
}, 
{ 
    question_id: "2", 
    EN: "Question 2 - EN", 
    FR: "Question 2 - FR", 
    isSelected: false 
} 

Meine Komponente beginnt:

export class FpPVQ implements OnInit { 
    private questions: any; 
    private lang: string; 
    private counter: number = 0; 
    private checkedLimit: number = 5; 
    private updateMode: boolean = false; 
    private createMode: boolean = false; 
    private deadlinePassed: boolean = false; 
    private previousScreen: string = ""; 
    private flowA: boolean = false; 
    private flowB: boolean = false; 
    private flowC: boolean = false; 
    private flowD: boolean = false; 
    private pvqForm: FormGroup; 
    private answer_0: FormControl; 
    private answer_1: FormControl; 
    private answer_2: FormControl; 
    private answer_3: FormControl; 
    private answer_4: FormControl; 
    private answer_5: FormControl; 
    private answer_6: FormControl; 
    private answer_7: FormControl; 
    private answer_8: FormControl; 
    private answer_9: FormControl; 
    private answer_10: FormControl; 
    private answer_11: FormControl; 
    private answer_12: FormControl; 
    private answer_13: FormControl; 
    private answer_14: FormControl; 
    private answer_15: FormControl; 
    private answer_16: FormControl; 
    private answer_17: FormControl; 
    private answer_18: FormControl; 
    private answer_19: FormControl; 
    private question_0: FormControl; 
    private question_1: FormControl; 
    private question_2: FormControl; 
    private question_3: FormControl; 
    private question_4: FormControl; 
    private question_5: FormControl; 
    private question_6: FormControl; 
    private question_7: FormControl; 
    private question_8: FormControl; 
    private question_9: FormControl; 
    private question_10: FormControl; 
    private question_11: FormControl; 
    private question_12: FormControl; 
    private question_13: FormControl; 
    private question_14: FormControl; 
    private question_15: FormControl; 
    private question_16: FormControl; 
    private question_17: FormControl; 
    private question_18: FormControl; 
    private question_19: FormControl; 


    private answerControlArr: Array<FormControl> = []; 
    private questionsArr: Array<any> = []; 



@ViewChild(DirtyModalComponent) public readonly dirtyModal: DirtyModalComponent; 

    constructor(private _pvqStepUp: PVQStepUpService, private _langToggle: ErrorToggleService, private router: Router) { } 

    ngOnInit() { 
    this.lang = window['appdata'].apiUserLanguage; 
    console.log('fpPVQ:: pvqStepUpData --> {}, ', this._pvqStepUp.data); 
    if (this._pvqStepUp.data != null) { 
     this.previousScreen = this._pvqStepUp.data.previousScreen; 
     this.questions = this._pvqStepUp.data.pvqs; 
     console.log('4176 FPVQ:: flow --> {}', this._pvqStepUp.data.flow); 
     switch(this._pvqStepUp.data.flow){ 
     case "A": this.flowA = true; break; 
     case "B": this.flowB = true; break; 
     case "C": this.flowC = true; break; 
     case "D": this.flowD = true; break; 
     } 
     this.questions.forEach(object => { 
     this.questionsArr.push([object.question_EN, object.question_FR, object.answer]); 
     console.log(object.question_id, object.EN, object.FR); 
     }) 
     if (this._pvqStepUp.data.deadlinePassed) 
     this.deadlinePassed = true; 
    } 

this.answer_0 = new FormControl('', Validators.required); 
this.answer_1 = new FormControl('', Validators.required); 
this.answer_2 = new FormControl('', Validators.required); 
this.answer_3 = new FormControl('', Validators.required); 
this.answer_4 = new FormControl('', Validators.required); 
this.answer_5 = new FormControl('', Validators.required); 
this.answer_6 = new FormControl('', Validators.required); 
this.answer_7 = new FormControl('', Validators.required); 
this.answer_8 = new FormControl('', Validators.required); 
this.answer_9 = new FormControl('', Validators.required); 
this.answer_10 = new FormControl('', Validators.required); 
this.answer_11 = new FormControl('', Validators.required); 
this.answer_12 = new FormControl('', Validators.required); 
this.answer_13 = new FormControl('', Validators.required); 
this.answer_14 = new FormControl('', Validators.required); 
this.answer_15 = new FormControl('', Validators.required); 
this.answer_16 = new FormControl('', Validators.required); 
this.answer_17 = new FormControl('', Validators.required); 
this.answer_18 = new FormControl('', Validators.required); 
this.answer_19 = new FormControl('', Validators.required); 

this.question_0 = new FormControl(); 
this.question_1 = new FormControl(); 
this.question_2 = new FormControl(); 
this.question_3 = new FormControl(); 
this.question_4 = new FormControl(); 
this.question_5 = new FormControl(); 
this.question_6 = new FormControl(); 
this.question_7 = new FormControl(); 
this.question_8 = new FormControl(); 
this.question_9 = new FormControl(); 
this.question_10 = new FormControl(); 
this.question_11 = new FormControl(); 
this.question_12 = new FormControl(); 
this.question_13 = new FormControl(); 
this.question_14 = new FormControl(); 
this.question_15 = new FormControl(); 
this.question_16 = new FormControl(); 
this.question_17 = new FormControl(); 
this.question_18 = new FormControl(); 
this.question_19 = new FormControl(); 

this.answerControlArr.push(this.answer_0); 
this.answerControlArr.push(this.answer_1); 
this.answerControlArr.push(this.answer_2); 
this.answerControlArr.push(this.answer_3); 
this.answerControlArr.push(this.answer_4); 
this.answerControlArr.push(this.answer_5); 
this.answerControlArr.push(this.answer_6); 
this.answerControlArr.push(this.answer_7); 
this.answerControlArr.push(this.answer_8); 
this.answerControlArr.push(this.answer_9); 
this.answerControlArr.push(this.answer_10); 
this.answerControlArr.push(this.answer_11); 
this.answerControlArr.push(this.answer_12); 
this.answerControlArr.push(this.answer_13); 
this.answerControlArr.push(this.answer_14); 
this.answerControlArr.push(this.answer_15); 
this.answerControlArr.push(this.answer_16); 
this.answerControlArr.push(this.answer_17); 
this.answerControlArr.push(this.answer_18); 
this.answerControlArr.push(this.answer_19); 

this.pvqForm = new FormGroup({ 
    answerControl0: this.answer_0, 
    answerControl1: this.answer_1, 
    answerControl2: this.answer_2, 
    answerControl3: this.answer_3, 
    answerControl4: this.answer_4, 
    answerControl5: this.answer_5, 
    answerControl6: this.answer_6, 
    answerControl7: this.answer_7, 
    answerControl8: this.answer_8, 
    answerControl9: this.answer_9, 
    answerControl10: this.answer_10, 
    answerControl11: this.answer_11, 
    answerControl12: this.answer_12, 
    answerControl13: this.answer_13, 
    answerControl14: this.answer_14, 
    answerControl15: this.answer_15, 
    answerControl16: this.answer_16, 
    answerControl17: this.answer_17, 
    answerControl18: this.answer_18, 
    answerControl19: this.answer_19, 
    questionControl0: this.question_0, 
    questionControl1: this.question_1, 
    questionControl2: this.question_2, 
    questionControl3: this.question_3, 
    questionControl4: this.question_4, 
    questionControl5: this.question_5, 
    questionControl6: this.question_6, 
    questionControl7: this.question_7, 
    questionControl8: this.question_8, 
    questionControl9: this.question_9, 
    questionControl10: this.question_10, 
    questionControl11: this.question_11, 
    questionControl12: this.question_12, 
    questionControl13: this.question_13, 
    questionControl14: this.question_14, 
    questionControl15: this.question_15, 
    questionControl16: this.question_16, 
    questionControl17: this.question_17, 
    questionControl18: this.question_18, 
    questionControl19: this.question_19 
}); 

    //Determine if Update or Create 
    if (this._pvqStepUp.data.flow !== 'A' && this._pvqStepUp.data.flow != "B") { 
     this.createMode = true; 
     this.counter = 0; 
    } else { 
     this.updateMode = true; 
     this.counter = 5; 
    } 

    this._langToggle.getLanguage().subscribe(
     lang => { 
     this.lang = lang.toString(); 
     }); 
    } 


    checkedState(event, checkBox) { 
    if (event.target.checked === true) { 
     if (this.counter < this.checkedLimit) { 
     this.counter++; 
     } else { 
     event.target.checked = false; 
     } 
    } else if (this.counter > 0) { 
     let index = event.target.name; 
     //When clicking off the checkbox, set value to null 
     this.answerControlArr[index].setValue(null); 
     this.counter--; 
    } 
    } 

    onSubmit(pvqForm: any) { 
    console.log('4176-21 Submitted data --> {}', pvqForm); 
    // console.log(pvqForm._value); 
    Object.keys(pvqForm._value).map((key) => { 
     console.log('4176-21 Object Key: ', key, ' Object Value: ', pvqForm._value[key]); 
     // console.log('Question Controm name ' + pvqForm._value[key]); 
     if(key.startsWith('questionControl')){ 
     } 
     if(key.startsWith('answerControl')){ 
     let index = key.replace('answerControl', ''); 
     console.log('Index is: ' + index); 
     console.log('Value is: ', pvqForm._value[key]); 
     } 
    }) 
    } 

    cancel() { 
    this.dirtyModal.show(); 
    } 

    modalStay() { 
    this.dirtyModal.hide(); 
    } 

    modalLeave() { 
    //Navigate Away to the previous screen 
    // this.router.navigate([this.previousScreen]); 
    location.assign(this.previousScreen); 
    } 

    isDisabled() { 
    if (this.counter == 5) { 
     //Enable if 5 Checkboxes are selected 
     return false; 
    } else { 
     //Disable if 5 Checkboxes are not selected 
     return true; 
    } 
    } 

} 

Die HTML:

<form [formGroup]="pvqForm" (ngSubmit)="onSubmit(pvqForm)" novalidate> 
     <div *ngFor="let question of questions | sortBy: 'selected'; let i = index" class="row container-generic"> 
     <div class="col-md-8"> 
      <div class="container-input-checkbox"> 
      <label class="container-flex"> 
      <input formControlName='questionControl{{i}}' #checkBox class="pvq-create-checkbox" type="checkbox" name="{{i}}" (change)="checkedState($event, checkBox)" [checked]="question.selected"> 
      <div class="pvq-create-label"> 
       <div *ngIf="lang == 'en'"> 
        <p aria-label="English Question">{{ question.EN }}</p> 
       </div> 
       <div *ngIf="lang == 'fr'"> 
        <p aria-label="French Question">{{ question.FR }}</p> 
       </div> 
      </div> 
      </label> 
      <label [@hideShow]="checkBox.checked ? 'show' : 'hide'">Answer 
      <input minlength=4 formControlName='answerControl{{i}}' type="textbox" name="{{i}}"> 
      <div *ngIf="!pvqForm.controls['answerControl' + i].valid && pvqForm.controls['answerControl' + i].touched" style="color: red;"> 
       Error here 
      </div> 
      </label> 
      </div> 
     </div> 
     </div> 

Antwort

1

Sie können ein entfernen Viele Ihrer Vervielfältigungen mit Form Arrays.

Diese können die Form Builder

Ich habe auch gruppiert Fragen und Antworten zusammen erstellt werden.

import { FormBuilder } from '@angular/forms' 

... 

ngOnInit() { 
    this.questionGroups = this.fb.array(this.getQuestions().map(question => this.fb.group(question))); 

    this.pvqForm = this.fb.group({ 
    questions: this.questionGroups 
    }); 

    console.log(this.pvqForm); 
} 

getQuestions() { 
    const questionControlArray = []; 
    for (let i = 0; i < 20; i++) { 
    questionControlArray.push({ 
     question: ['', Validators.required], 
     answer: [''] 
    }); 
    } 
    return questionControlArray; 
} 

Dann würden sie in der Ansicht so etwas wie angezeigt:

<form [formGroup]="pvqForm" (ngSubmit)="submit(pvqForm)"> 
    <div [formArrayName]="'questions'"> 
    <div *ngFor="let question of questionGroups.controls; let i = index;" class="form-group"> 
     <div [formGroupName]="i"> 
     <label class="center-block">{{'question ' + i}}: 
      <input formControlName="question" class="form-control"/> 
     </label> 
     <label class="center-block">{{'answer ' + i}}: 
      <input formControlName="answer" class="form-control"> 
     </label> 
     </div> 
    </div> 
    </div> 

    <button>Submit</button> 
</form> 
+0

Danke, aber das ist nicht, was ich gesucht habe. Vielleicht könnte ich Form-Arrays zu meinem Advtange verwenden und eine Lösung finden. Bis dahin noch verloren. –

+0

Ok, du versuchst also, Fragen mit Antworten zu assoziieren und kannst das nicht, weil sich die Reihenfolge ändert, aber die IDs sind nicht richtig? Könnten Sie ein Bild von dem, wie die Komponente aussieht, veröffentlichen? Ich fürchte, es gab zu viele fehlenden Abhängigkeiten für mich um die Komponente zu schaffen ich – 0mpurdy

+0

Ja, wenn es eine Möglichkeit, die Frage oder die ID der Frage mit der Antwort auf die Gruppe, dass die Art, wie ich herausfinden kann, welche Antwort abgeschlossen war durch der Benutzer für die entsprechende Frage. Der ngFor-Index ist nur ein Index für die Amiunt von Fragen in thebarray, wenn sortiert die Frage Id nicht äquivalent zum Index ist. Ich habe den Komponentencode gepostet. Ich kann später Screenshots machen, wenn ich zu Hause bin. –