#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. Еще раз спасибо за ваше время и помощь.