Создание динамической формы в угловых, добавление полей во время выполнения - PullRequest
1 голос
/ 10 ноября 2019

Я делаю сайт, на котором я могу создавать экзамены с несколькими вариантами ответов. У меня есть HTML-страница, на которой я могу добавить вопросы к экзамену.

Вопрос состоит из описания вопроса и нескольких вариантов. Опция содержит ответ и значение, чтобы проверить, является ли ответ истинным или ложным.

Пользователь должен иметь возможность добавлять опции к вопросу при заполнении формы. Я пытаюсь использовать formbuilder, formgroup и formarray для этого, но это не работает. Когда я нажимаю опцию добавления, должен появиться новый ответ и новое действительное поле.

form

Поля появляются на моей HTML-странице, но я получаю эту ошибку при заполнениисформироваться. "Не удается найти элемент управления с ответом на имя" + "не удается найти элемент управления с именем действительным"

Это страница HTML:

    <form [formGroup]="questionForm" (ngSubmit)="onSubmit(questionForm.value)">
        <div>
          <label>Description:</label>
          <br />
          <input class="form-control" id="description" type="text" formControlName="description">
          <br />
          <label>Options</label>

          <div *ngFor="let test of arrayOptions; let i = index">
            <div class=mx-4>
              <label>Response</label>
              <input class="form-control" id="response" type="text" formControlName="response">
              <label>Valid</label>
              <input class="form-control" id="valid" type="text" formControlName="valid">
            </div>


          </div>

          <button type="button" class="btn-block-option text-primary" (click)="addOption()">
            <i class="fa fa-plus" aria-hidden="true"></i>Add option
          </button>


        </div>
        <div class="block-content block-content-full block-content-sm bg-body-light font-size-sm">
          <button class="btn btn-primary" type="submit">Add</button>
        </div>
      </form>

Это моя страница ts:

    export class AddQuestionComponent implements OnInit {

      questionForm;
      arrayOptions;

      constructor(
        private examSimulatorService: ExamSimulatorService,
        private formBuilder: FormBuilder
      ) {
        this.questionForm = this.formBuilder.group({
          description: '',
          options: ''
        })
      }
      removeOption(i) {
        this.questionForm.removeControl(i);
      }
      addOption() {

    this.questionForm.addControl(this.questionForm.controls.options.value, 
    this.formBuilder.array([this.formBuilder.group(
          {
            response: "",
            valid: ""
          }
        )]));
        this.arrayOptions.push(this.questionForm.controls.options.value);
      } 

      onSubmit(questionData) {
        this.examSimulatorService.addQuestion(questionData);
        this.questionForm.reset();
      }

      ngOnInit() {
        this.arrayOptions = [];
        this.addOption();
      }

    }

Ответы [ 2 ]

1 голос
/ 10 ноября 2019

Трудно сказать точные ошибки без работающего образца.

Некоторые вещи, которые я заметил:

1) Когда мы используем FormArray, мы должны связать его в шаблонечерез formArrayName

2) Я не совсем понимаю, почему вы звоните addControl в форме вопроса. Не должны ли мы вставить новую опцию в FormArray?

Пример формы с FormArray:

this.questionForm = this.fb.group({
  question: ["Sample Question"],
  options: this.fb.array([
    this.fb.group({
      response: ["Response Example"],
      valid: [true]
    })
  ])
});

Ссылка FormArray в шаблоне через formArrayName:

<form [formGroup]="questionForm">
  <input type="text" formControlName="question" />

  <div formArrayName="options">

    <div *ngFor="let option of options.controls; let i=index">
      <b>Option {{i}}:</b>
      <div [formGroupName]="i">
          <input type="text" formControlName="response" />
          <input type="checkbox" formControlName="valid" />
      </div>
    </div>

</div>
</form>

Наконец, метод добавления новой опции:

addOption() {
  this.options.push(
    this.fb.group({
      response: [""],
      valid: [false]
    })
  );
}

// getter which simplifies the access via 'this.options' used in the addOption method
get options() {
  return this.myForm.get("options") as FormArray;
}

Взгляните на codesandbox . Не стесняйтесь раскошелиться и отредактировать его, чтобы он лучше показал вашу проблему.

1 голос
/ 10 ноября 2019

Вы не добавили formArray и formGroup в ваш HTML

HTML-код:

<form [formGroup]="questionForm" (ngSubmit)="onSubmit(questionForm.value)">
<div>
   <label>Description:</label>
   <br />
   <input class="form-control" id="description" type="text" formControlName="description">
   <br />
   <label>Options</label>
   <div formArrayName="options">
      <div *ngFor="let test of arrayOptions; let i = index">
         <div class=mx-4 [formGroupName]="i">
            <label>Response</label>
            <input class="form-control" id="response" type="text" formControlName="response">
            <label>Valid</label>
            <input class="form-control" id="valid" type="text" formControlName="valid">
         </div>
      </div>
   </div>
   <button type="button" class="btn-block-option text-primary" (click)="addOption()">
   <i class="fa fa-plus" aria-hidden="true"></i>Add option
   </button>
</div>
<div class="block-content block-content-full block-content-sm bg-body-light font-size-sm">
   <button class="btn btn-primary" type="submit">Add</button>
</div>
</form>

Компонент:

export class AppComponent implements OnInit {
  questionForm;
  arrayOptions;
  constructor(private formBuilder: FormBuilder) {
    this.questionForm = this.formBuilder.group({
      description: "",
      options: this.formBuilder.array([])
    });
  }

  ngOnInit() {
    this.arrayOptions = [];
    this.addOption();
  }

  removeOption(i) {
    this.questionForm.removeControl(i);
  }

  addOption() {
    const control = <FormArray>this.questionForm.get("options");
    const newGroup = this.formBuilder.group({
      response: "",
      valid: ""
    });
    control.push(newGroup);
    this.arrayOptions.push(this.questionForm.controls.options.value);
  }

  onSubmit(questionData) {
    console.log(questionData);
  }
}

Найтикод здесь

...