Angular - FormBuilder, как сгруппировать несколько элементов управления формой

Я использую Formbuilder для создания FormGroup:

myForm = this.fb.group(
            {
                title: [""],
                fixed_grade1: [""],
                fixed_value1: [""],
                fixed_grade2: [""],
                fixed_value2: [""],
                fixed_grade3: [""],
                fixed_value3: [""],
                fixed_grade4: [""],
                fixed_value4: [""]
            });

все fixed_grade и fixed_value являются входами и раскрывающимися списками.

У меня их 4 пары, и это работает правильно.

Но теперь я хотел бы сгруппировать их, чтобы мне не приходилось обращаться к каждому значению в моем контроллере одно за другим, с myForm.get("fixed_grade1").value для каждого.

Но я бы хотел, чтобы все эти значения были сгруппированы в массив, например:

myArray: [{grade, value}, [grade, value}...]

поэтому я могу получить доступ к их значению: myArray[0].grade

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

Каким будет правильный синтаксис для достижения того, что я описал, имея ровно 4 пары оценок / оценок, а также важно, чтобы в моем окончательном массиве со всеми этими парами оценка / оценка у меня были только значения, которые не являются неопределенными, поэтому, если в моей форме пользователь заполняет только одну пару оценок / баллов, тогда мой myArray.length будет равен 1.


person AJ989    schedule 24.10.2018    source источник


Ответы (1)


Вы неправильно определили свой FormGroup. У вашего FormGroup должно быть FormArray из FormGroup. Внутри каждого из этих FormGroup должно было быть два FormControl для grade и value.

Измените свою форму на это:

const grades = [
  {grade: 'Grade 1', value: 'Value 1'},
  {grade: 'Grade 2', value: 'Value 2'},
  {grade: 'Grade 3', value: 'Value 3'},
  {grade: 'Grade 4', value: 'Value 4'}
]

myForm = this.fb.group({
  title: [],
  grades: this.fb.array(this.grades.map(grade => this.fb.group({
    grade: [grade.grade],
    value: [grade.value]
  }))),
});

// OR

myForm = this.fb.group({
  title: [],
  grades: this.fb.array(this.grades.map(grade => this.fb.group({
    grade: [],
    value: []
  }))),
});
...
get gradesArray() {
  return (<FormArray>this.myForm.get('grades')).controls;
}
...
getArrayGroupControlByIndex(index) {
  return (<FormArray>this.myForm.get('grades'))
    .at(index);
}

Вот как вы будете использовать его в шаблоне:

<form [formGroup]="myForm">
  <input type="text" formControlName="title">
  <br>
  <div formArrayName="grades">
    <div *ngFor="let gradeGroup of gradesArray; let i = index;">
      <div [formGroupName]="i">
        Group {{ i + 1 }}
        <input type="text" formControlName="grade">
        <input type="text" formControlName="value">
      </div>
      <br>
    </div>
  </div>
</form>

Вот Образец StackBlitz < / a> для вашего исх.

person SiddAjmera    schedule 24.10.2018
comment
хорошо, я попробую это, я пробовал сделать: fixed_pairs: this.fb.array ([this.createPairs ()]), а затем метод createPairs - ›createPairs (): FormGroup {return this.fb.group ({grade : , счет: }); } но я получал ошибки, ваш путь кажется достаточно ясным, я попробую и дам вам знать - person AJ989; 24.10.2018
comment
и дополнительный вопрос о том, как мой конструктор форм был настроен раньше, на мой взгляд, у меня было formControlName = fixed_value1 для каждого значения, если я буду следовать вашему пути, как я могу назначить в моем шаблоне каждое из этих значений массива formBuilder для ввод или выпадающий список? - person AJ989; 24.10.2018
comment
вот и все, работает отлично, именно то, что мне нужно! И последнее: если для отдельных значений другого поля моего конструктора форм я получал такие данные: myForm.get (title) .value и подписывался на изменения с помощью .valueChanges, как мне получить доступ к определенному значению этого новая форма Массив? myForm.get (оценки) [x] .grade.value? где x - индекс объекта, к которому я хочу получить доступ? А пока отметьте свой ответ как правильный! Спасибо - person AJ989; 24.10.2018
comment
@ AJ989, просто взгляните на метод getArrayGroupControlByIndex, который я только что добавил к своему ответу. - person SiddAjmera; 24.10.2018
comment
да, я нашел это решение также в stackoverflow, спасибо, пытаясь выяснить последнее, как вручную установить значение, для других отдельных значений, которые я только что использовал .get (xx) .setValue, здесь я пытаюсь сделать : (‹FormArray› this.myForm.get ('оценки')) .at (индекс) .grade.setValue (x); но похоже, что это не работает! - person AJ989; 24.10.2018
comment
ок, nvm, нашел решение для этого! спасибо большое, теперь все ясно - person AJ989; 24.10.2018
comment
Я сделал это так: (‹FormArray› this.myForm.get ('оценки')). At (index) [controls] .grade.setValue (x, {onlySelf: true}); - person AJ989; 24.10.2018