(Угловой) Работа с массивом данных из API

#angular #api #angular-reactive-forms #formarray

Вопрос:

Что касается некоторых данных, полученных через службу для API. Данные (данные) получены и показаны в таблице на интерфейсном приложении (Angular), где я ставлю флажки для каждой строки. Идея заключается в том, что пользователь должен иметь возможность отмечать флажки, которые он хотел бы добавить в свое бронирование.

API должен использовать модель бронирования с одним ко многим лежаками, однако я ни за что на свете не смогу заставить ее работать. При проверке консоли браузеров массив объектов либо «Не определен», либо я могу заставить его отображать только один из 3 атрибутов (идентификатор, зона или Тип), где для объекта бронирования необходим весь объект.

Я должен сказать, что я стремился к успеху в этом проекте, так как моего опыта работы с JS/TS и HTML тоже очень не хватает, и это становится очевидным сейчас. Я погуглил и попытался многое изменить, но здесь я действительно в растерянности. Я уверен, что для этого есть какое-то простое решение, на которое сможет указать кто-то с большим опытом. Спасибо!

бронирование.ts (модель)

 import { Lounger } from "./lounger";

export class Reservation {
    id: string;
    date: string;
    startTime: string;
    endTime: string;
    userId: string;
    loungers: Lounger[];
}
 

шезлонг.ts (модель)

 export class Lounger {
    id: string;
    type: string;
    zone: string;
}
 

добавить-редактировать-компонент.ts

 export class AddEditComponent implements OnInit {
    reservationForm: FormGroup;
    id: string;
    isAddMode: boolean;
    loading = false;
    submitted = false;
    user: User;
    reservation: Reservation;
    loungersFromApi: Lounger[];

    constructor(
        private formBuilder: FormBuilder,
        private route: ActivatedRoute,
        private router: Router,
        private reservationService: ReservationService,
        private alertService: AlertService,
        private accountService: AccountService,
        private loungerService: LoungerService
    ) {
        this.user = this.accountService.userValue;
    }
    

    ngOnInit() {
        this.id = this.route.snapshot.params['id'];
        this.isAddMode = !this.id;

        this.loungerService.getAll()
        .pipe(first())
        .subscribe(x => this.loungersFromApi = x);

        this.reservationForm = this.formBuilder.group({
            date: ['', Validators.required],
            startTime: ['', Validators.required],
            endTime: ['', Validators.required],
            userId: [this.user.id],
            loungers: this.formBuilder.array([], Validators.required)
        });
    }

onCheckboxChange(e) {
    const loungers: FormArray = this.reservationForm.get('loungers') as FormArray;

    if (e.target.checked) {
        loungers.push(new FormControl(e.target.value));
    } else {
        let i: number = 0;
        loungers.controls.forEach((item: FormControl) => {
            if (item.value == e.target.value) {
                loungers.removeAt(i);
                return;
            }
            i  ;
        });
    }
}

get f() { return this.reservationForm.controls; }
 

}

add-edit.component.html

 <form [formGroup]="reservationForm" (ngSubmit)="onSubmit()">

<div>
         <div *ngFor="let lounger of loungersFromApi; let i=index">
                <label>
                  <input type="checkbox" [value]="lounger.id" (change)="onCheckboxChange($event)" />
                  {{lounger.id}}
                </label>
              </div>
        </div>
    </form>
 

Ответ №1:

Хотя вы могли бы добавить объект в качестве элемента управления формой, я бы вместо этого добавил его в качестве группы форм.

Мы можем использовать find для сравнения значения event.target.value в вашем loungersFromApi , чтобы оно соответствовало id (которое вы используете). Шаблон остается таким же, как у вас, но в нем всего несколько изменений, onCheckboxChange чтобы добавить группы форм:

 onCheckboxChange(e) {
  const loungers: FormArray = this.reservationForm.get(
    'loungers'
  ) as FormArray;

  if (e.target.checked) {
    // use find to find the matching item
    const item = this.loungersFromApi.find(x => x.id === e.target.value);
    if (item) {
      // push a formgroup instead with the whole object
      loungers.push(this.formBuilder.group(item));
    }
  } else {
    let i: number = 0;
    loungers.controls.forEach((item: FormControl) => {
      // again, find the item in your array by id
      if (item.value.id == e.target.value) {
        loungers.removeAt(i);
        return;
      }
      i  ;
    });
  }
}
 

Вот очищенная версия вашего кода. Просто в качестве предложения посмотрите на код, представленный в Stackblitz, который я связал, поскольку ваша проблема связана только с флажками, это действительно то, что вам нужно показать, чтобы это был минимальный воспроизводимый пример. Вы, скорее всего, получите ответы, если проблема будет четко представлена и весь ненужный код будет удален. Никто не хочет просеивать кучу кода, чтобы попытаться найти проблему… Хорошо… Я только что сделал 😀

СТЕКБЛИТЦ для вашей справки

Комментарии:

1. Всем привет и большое вам спасибо за потраченное время! Я попробовал ваше решение с изменением метода onCheckboxChange, но, к сожалению, оно все равно не сработает. Это вывод в браузере: imgur.com/a/wMMZ1Gj Я буду продолжать пытаться, но, пожалуйста, вернитесь, если вы видите, что не так. Мы ценим ваши усилия!

2. @t_hound Я дал вам рабочий образец на stackblitz, если у вас возникли проблемы, пожалуйста, раскошелитесь на stackblitz с текущим кодом, который у вас есть, и воспроизведите проблему. Иначе помочь не могу, так как это работает в демо, которое я сделал.

3. Извините, что потянулся. Я попытался прокомментировать метод GetAll из сервиса и просто использовал статический массив — и тогда он работает. Таким образом, проблема должна быть связана с объектом обслуживания/наблюдения.

4. Вам нужно отладить, проверить, что вы получаете от бэкенда, совпадают ли значения, соответствуют ли свойства. Инструменты разработки отлично подходят для этого. И журналы консоли повсюду, чтобы увидеть, с чем вы работаете 🙂

5. Да, погуглив разницу в 1-3 знаках равенства, я тоже пришел к этому пониманию. Возможно, это было бы заметно, если бы я работал в другом проекте, где для меня был установлен строгий режим true. Еще раз спасибо за ваше время и помощь.