ngModel inside ngFor - Angular/Ionic

Asked

Viewed 282 times

0

I try to create a test with several questions and each question has 4 answers, my logic is, the first ngFor is the number of questions and the second is your answers. My problem is that when I type a text in the letter A, every question is affected. In the image, I wrote the answers in question_2, but each question gets these answers.

inserir a descrição da imagem aqui

My html code:

<ion-slide *ngFor="let question of listQuestions; let indexQuestion = index ;">
 <div>
  <div>
    <div>{{question.numberQuestion}}</div>
  </div>
 </div>

 <div padding>
  <span></span>
  <ion-item>
    <ion-textarea rows="3" [(ngModel)]="questionClosed.statement"></ion-textarea>
  </ion-item>

  <ion-row *ngFor="let letter of listLetters; let index = index ;">
    <ion-col col-1 (click)="selectAnswer(letter)">
      <span >{{letter}}</span>
    </ion-col>
    <ion-col>
      <ion-item>
        <ion-textarea rows="2" [(ngModel)]='responses["question_" + (question.numberQuestion).toString()][letter]'></ion-textarea>
      </ion-item>
    </ion-col>
  </ion-row>
 </div>
</ion-slide>

My code ts:

public questionClosed: { statement?: string; A?: string; B?: string; C?: string; D?: string; } = {
  statement: null,
  A: null,
  B: null,
  C: null,
  D: null
};
public responses: any = {};

populatedListQuestions(numberQuestions) {
 for (let i = 0; i < numberQuestions; i++) {
  const data = {
    numberQuestion: i + 1,
    description: this.questionClosed
  };
  this.listQuestions.push(data);
  let name = 'question_' + (i+1).toString();
  this.responses[name] = this.questionClosed;
 }
} 

1 answer

2


From what I understand you have a list of questions, which have a list of answers, correct?

If so, I recommend working your model with better defined classes, an Entity and a Value Object set, such as these:

class Question {
  id: number;
  description: string;
  answers: Array<Answer>;

  constructor(id: number, description: string, answers: Array<Answer>) {
    this.id = id;
    this.description = description;
    this.answers = answers;
  }

  isValid() {
    return !!this.id &&
      !!this.description &&
      !!this.answers &&
      !!this.answers.find(answer => !answer.isValid())
  }
}

class Answer {
  letter: string;
  description: string;

  constructor(letter: string, description: string) {
    this.letter = letter;
    this.description = description;
  }

  isValid() {
    return this.letter.length === 1 && !!this.description;
  }
}

Your page.ts file could look like this:

  public questions: Array<Question> = [];

  createQuestions(questionsNumber) {
    for (let i = 0; i < questionsNumber; i++) {
      const answers = [
        new Answer('A', ''),
        new Answer('B', ''),
        new Answer('C', ''),
        new Answer('D', ''),
      ];
      const question = new Question(i + 1, '', answers);
      this.questions.push(question);
    }
  }

  ngOnInit() {
    this.createQuestions(5);
  }

  submitAnswers() {
    console.log(this.questions);
  }

And your . html like this:

<ion-slide *ngFor="let question of questions;">
  <div>
    <div>
      <div>{{question.id}}</div>
    </div>
  </div>

  <div padding>
    <ion-row *ngFor="let answer of question.answers;">
      <ion-col col-1>
        <span>{{answer.letter}}</span>
      </ion-col>
      <ion-col>
        <ion-item>
          <ion-textarea rows="2" [(ngModel)]='answer.description'>
          </ion-textarea>
        </ion-item>
      </ion-col>
    </ion-row>
  </div>
  <button (click)="submitAnswers()">Submit</button>
</ion-slide>

Simulating here worked well without giving problems:simulando...

Note: Using the app created from Ionic cli

  • Perfect, it’s been almost a week on this, thank you very much!!!!!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.