Вложенная угловая реактивная форма и ошибка с нахождением контроля - PullRequest
0 голосов
/ 03 января 2019

Я хочу создать форму в Angular, которая может отправлять массив объектов.

В результате я хочу получить такой Json:

order = {
 selectedDays: [{
  meals: [
    {name: 'breakfast',
    selected: false},
    {name: 'dinner',
    selected: false},
    {name: 'supper',
    selected: false}
  ],
  selectedDay: "10/01/2018"
}
]}

Однако у меня возникли некоторые проблемы с поиском элемента управления.Я получаю эту ошибку:

Ошибка: не удается найти элемент управления с путем: 'selectedDays -> 0 -> питание -> завтрак'

Вот мой код:

HTML:


 

Chosen day {{i+1}}:
Choose date
breakfast
dinner
supper
Form values: {{form.value | json}}

И машинопись:

export class OrderFormComponent implements OnInit {

public form: FormGroup;
public availableMeals: string[] = [
  "breakfast", "dinner", "supper"
];

order = {
  selectedDays: [
    {
      meals: [
        {name: 'breakfast',
        selected: false},
        {name: 'dinner',
        selected: false},
        {name: 'supper',
        selected: false}
      ],
      selectedDay: "10/01/2018"
    }
  ]
}
  
constructor(private orderService: OrderService,
            private formBuilder: FormBuilder) { 
  this.form = this.formBuilder.group({
    selectedDays: this.formBuilder.array([])
  })
 
  this.setSelectedDays();
}

addNewDay() {
  let control = <FormArray>this.form.controls.selectedDays;
  control.push(
    this.formBuilder.group({
      meals: this.formBuilder.array([]),
      selectedDate: new FormControl((new Date()))
    })
  )
}

setSelectedDays() {
  let control = <FormArray>this.form.controls.selectedDays;
  this.order.selectedDays.forEach(x => {
    control.push(this.formBuilder.group({ 
      meals: this.mapToCheckboxArrayGroup(this.availableMeals),
      selectedDate: x.selectedDay
    }))
  })
}

submit() {
  this.orderService.sendOrder(this.form.value).subscribe(() => {
      console.log("Order added");
    },
    err => {
      console.log('error occurred: ' + err.message);
    }
  );
}

private mapToCheckboxArrayGroup(data: string[]): FormArray {
  return this.formBuilder.array(data.map((meal) => {
    return this.formBuilder.group({
      name: meal,
      selected: false
      });
    }));
  }
}

объект my Day.ts:

export interface Day {
    meals: [
        {name: 'breakfast',
        selected: boolean},
        {name: 'dinner',
        selected: boolean},
        {name: 'supper',
        selected: boolean}
    ]
    selectedDay: string;
  }
  

Вероятно, есть кое-что, что я пропустил, однако я не могу решить это самостоятельно - я довольно плохо знаком с Angular.Буду благодарен за помощь!

1 Ответ

0 голосов
/ 03 января 2019

Итак, после создания моей собственной версии . Есть несколько вещей для обсуждения. Во-первых, вы используете formControlName в следующем коде

<div class="col-md-3" formArrayName="meals">
    <div><mat-checkbox formControlName="breakfast"> breakfast </mat-checkbox> </div>
    <div><mat-checkbox formControlName="dinner"> dinner </mat-checkbox> </div>
    <div><mat-checkbox formControlName="supper"> supper  </mat-checkbox> </div> 
</div>

Проблема в том, что у ваших элементов управления нет имен. Если вы откроете форму в консоли, вы заметите, что она выглядит как FormGroup -> Controls -> Meals -> Controls -> 0-3. Вам придется повторить их снова и попытаться извлечь имя из самого объекта. Оказывается, это действительно тяжело , по крайней мере, для меня это так. Вместо этого вы можете назначить переменную индексу массива, как вы это сделали для selectedDays, а затем использовать итератор для доступа к свойству meals order.selectedDays[i].

Если вы сделаете это, вы в конечном итоге переключитесь с жесткого кодирования различных флажков и выберете *ngFor, который будет автоматически извлекать информацию, и присвоить значение свойства selected в order.selectedDays[i].meals[m] чекбокс через [(ngModel)].

Посмотрите на пример StackBlitz, с которым я связан, я знаю, что он выглядит совершенно иначе с точки зрения дизайна, но методы, которые я упомянул, используются. Элемент управления, который вас заинтересовал бы в поиске упомянутого метода итерации, - это элемент управления order-form, обратите внимание, что в этом элементе управления я использую get meals(): FormArray { return this.form.get('meals') as FormArray; }, что позволило мне использовать [formControlName] = "i".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...