Angular Dynamic Reactive Form Вложенный массив FormArray для кнопок радио

При вызове API у меня есть Массив вопросов и их варианты JSON.

 [
  {
    "QuestionText": "Question goes here...",
    "AnswerChoice": [
      {
        "text": "text1",
        "answerId": "1"
      },
      {
        "text": "text2",
        "answerId": "2"
      },
      {
        "text": "text3",
        "answerId": "3"
      },
      {
        "text": "text4",
        "answerId": "4"
      },
      {
        "text": "text5",
        "answerId": "5"
      }
    ],
    "questionId": "1"
  },
  {
    "QuestionText": "Second question goes here...?",
    "AnswerChoice": [
      {
        "text": "text1",
        "answerId": "1"
      },
      {
        "text": "text2",
        "answerId": "2"
      },
      {
        "text": "text3",
        "answerId": "3"
      },
      {
        "text": "text4",
        "answerId": "4"
      },
      {
        "text": "text5",
        "answerId": "5"
      }
    ],
    "questionId": "2"
  }
  ... and so on.
]

Варианты ответа - это переключатели в пользовательском интерфейсе.

Итак, теперь вопрос.

Я пытаюсь создать реактивную форму для этой проблемы. Я не могу найти решения. Я пытаюсь создать вложенные массивы форм, но тщетно.

Мои попытки решить эту проблему:

HTML -

        <form [formGroup]="eidFormSubmission">
        <div>
            <div *ngFor="let question of questions; let i = index">
                <p>
                    {{i+1}}. {{question.QuestionText}}
                </p>
                <div class="form-group">
                    <div>
                        <div class="custom-control custom-radio"
                            *ngFor="let answer of question.AnswerChoice let k=index">
                            {{question.questionId}}
                            <input [value]="answer.answerId" type="radio" formControlName="i"
                                id="{{question.questionId}}" name="quesAnswer"
                                class="custom-control-input">
                            <label class="custom-control-label" for="{{question.questionId}}">
                                {{ answer.text }}</label>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <button (click)="onSubmitAnswers()" class="btn btn-primary">Next</button>
    </form>

TS -

  eidFormSubmissionInit(){
    const formArray = this.formBuilder.array([]);
    this.eidFormSubmission = this.formBuilder.group({
      questions: formArray
    })
  }

Теперь я не понимаю, как динамически вставлять (после ответа API) в formbuilder.

И вторая проблема связана с переключателем, когда я выбираю вариант из второго вопроса, он отменяет выбор из первого вопроса.

Любая помощь будет оценена по достоинству!


person Raj Amit Singh    schedule 19.03.2020    source источник
comment
Попробуйте создать пример stackblitz, который вам поможет.   -  person Tzimpo    schedule 19.03.2020


Ответы (1)


Проверь это:

Сначала создайте такую ​​форму с «вопросами» внутри как FormArray:

this.eidFormSubmission = this.fb.group({
  questions: this.fb.array([])
});

after в вашем ngOnInit, когда вы получаете вопросы, прокрутите каждый вопрос и добавьте новый элемент в formArray "questions"

  ngOnInit() {
    this.dataService.getQuestions().subscribe((data: any[]) => {
      console.log(data);
      this.questions = data;

      this.questions.forEach(question => {
        (this.eidFormSubmission.get('questions') as FormArray).push(this.addQuestionFormGroup(question));
      });
    });
  }

с помощью этой служебной функции:

  private addQuestionFormGroup(question: any): FormGroup {
    return this.fb.group({
      QuestionText: question.QuestionText,
      AnswerChoice: new FormControl()
    });
  }

разметка html:

<form (ngSubmit)="onSubmitAnswers()" [formGroup]="eidFormSubmission">
  <table>
    <tr formArrayName="questions" *ngFor="let data of eidFormSubmission.get('questions').controls; let i = index">
      <ng-container [formGroupName]="i">
        <th>
          <input type="text" formControlName="QuestionText" readonly>
        </th>
        <th *ngFor="let answer of questions[i].AnswerChoice">
          <input type="radio" formControlName="AnswerChoice" value="{{answer.answerId}}">{{answer.text}}
        </th>
      </ng-container>
    </tr>
  </table>
  <br>
  <button type="submit">Submit</button>
</form>

Рабочий stackblitz

person robert    schedule 19.03.2020
comment
Спасибо за понятный ответ, он также помогает мне прояснить мою базовую концепцию ng-форм. - person Raj Amit Singh; 20.03.2020