该页面是创建企业及其1个或多个设施的表单。 每个机构都有一个地址。 我必须保存这一切。
所以我必须循环所有机构来保存其地址,然后将后端发送的addressId放入EnterpriseRequestModel中,然后保存企业。
我不知道如何做到这一点,我想这是 ForkJoin、MergeMap 等的某种组合,但我还不完全理解 RxJs 运算符,所以我需要一些帮助,谢谢。
[编辑]
好吧,现在该组件不支持多个设施,只有一个设施,保存所有这些的函数如下所示:
public onSave(): void {
this.isLoading = true;
const siren = this.entepriseWithEstablishmentFormGroup.controls.enterpriseFormGroup.controls.siren.value;
const enterprise = this.entepriseWithEstablishmentFormGroup.controls.enterpriseFormGroup.getRawValue();
const establishment = this.entepriseWithEstablishmentFormGroup.controls.establishmentFormGroup.getRawValue();
const siret = `${siren}${establishment.siret}`;
const establishmentRM = new EstablishmentRequestModel(establishment.name, siret, establishment.email, establishment.phone, null, establishment.addressId);
const enterpriseRM = new EnterpriseWithEstablishmentRequestModel(enterprise.name, enterprise.siren, establishmentRM);
this.isLoading = true;
// create enterprise and establishment in a row
this.subscriptions.add(
this.enterpriseService
.createEstablishmentAddress(this.addressFormGroup.getRawValue())
.pipe(
map((addressId) => addressId),
catchError((error: HttpErrorResponse) =>
throwError(() => {
this.isLoading = false;
this.toastr.error(this.translatePipe.transform('COMPANY.DIALOGS.CREATE.ERROR-MSG.PERSISTENCE-ERROR'), this.translatePipe.transform('ADDRESS.DIALOGS.CREATE.TITLE'));
})
),
switchMap((addressId) => {
enterpriseRM.establishment.addressId = addressId;
this.entepriseWithEstablishmentFormGroup.controls.establishmentFormGroup.controls.addressId.patchValue(addressId);
//this.showAddressForm = false;
return this.enterpriseService.createEnterpriseWithEstablishment(enterpriseRM).pipe(
map((response) => response),
catchError((error: HttpErrorResponse) =>
throwError(() => {
this.isLoading = false;
this.toastr.error(this.translatePipe.transform('COMPANY.DIALOGS.CREATE.ERROR-MSG'), this.translatePipe.transform('COMPANY.DIALOGS.CREATE.TITLE'));
})
)
);
})
)
.subscribe((response) => {
this.isLoading = false;
if (response !== null) {
this.dialogRef.close(response);
}
})
);
但如你所知,我现在必须为多个机构这样做。 保存地址的api和保存企业/机构的api是不同的。
基本上,我拥有的数据是这样的:
Enterprise : {
socialReason: Apple;
siren: 1248746392;
establishment: [
{
name: Apple London;
siret: 129838;
addressId: null;
enterpriseId: null;
},
{ ...
]
}
如果没有addressId,我无法保存酒店。我明白你所说的让 ORM 管理对象,但它是这样完成的,我必须处理它..(而且我不是后端开发人员)
为了将来的参考,这是我找到并工作的答案:
public onSave(): void {
this.isLoading = true;
const enterpriseFormGroup = etc...;
const enterpriseRM = etc...;
this.enterpriseService.createEnterprise(enterpriseRM).subscribe((enterpriseId: number) => {
if (enterpriseId) {
this.saveEstablishments(enterpriseId);
}
});
}
private saveEstablishments(enterpriseId: number): void {
const siren = siren.value;
const establishmentList = this.getEstablishmentList(siren);
const apiCall = (establishment: EstablishmentWithAddress) =>
this.enterpriseService.createEstablishmentAddress(establishment.address).pipe(
map((addressId) => addressId),
catchError((error: HttpErrorResponse) =>
throwError(() => {
this.isLoading = false;
this.toastr.error(...);
})
),
mergeMap((addressId: number) => {
const establishmentRM = new EstablishmentRequestModel(addressId);
return this.enterpriseService.createEstablishment(establishmentRM).pipe(
map((response) => response),
catchError((error: HttpErrorResponse) =>
throwError(() => {
this.isLoading = false;
this.toastr.error(...);
})
)
);
})
);
const apiCalls = Array.from(establishmentList, (v, i) => apiCall(v));
const numberOfSimultaneousRequests = 1;
let processedRows = 0;
this.subscriptions.add(
of(...apiCalls)
.pipe(mergeMap((savedData) => savedData, numberOfSimultaneousRequests))
.subscribe({
next: (savedData) => {
processedRows++;
},
error: (err) => {
console.log('error:', err);
},
complete: () => {
if (processedRows === establishmentList.length) {
this.isLoading = false;
this.dialogRef.close({
id: enterpriseId,
establishmentId: null,
});
}
},
})
);
}
这个想法是创建一个函数调用数组(两个函数用 mergeMap、createAdress > createEstablished 链接起来)。然后用建立列表调用数组并用mergeMap执行数组。
开发起来真的很痛苦