如何处理 Angular 中的大 URL 参数
How to handle large URL parameters in Angular
在我的酒店预订应用程序中,它由多个阶段组成,例如 Hotel Search -> Select Hotel -> Select Room -> Payment 和每个阶段有不同的页面。所有阶段都需要来自前一阶段的许多输入(在某些情况下大约 5-8 个),例如会话 ID、签入、签出等。我使用查询参数进行应用内导航,因为当用户刷新页面时它不应该中断。
我面临的问题是,太多的字段使 URL 变得丑陋,并且 nginx 在某些阶段也会因为 URL 大而抛出错误。我曾尝试将这些数据存储在服务中,但它没有帮助,因为刷新页面时数据丢失并且存储在 localStorage
中看起来不太好。那么,在这里我可以采取什么正确或最佳方法来避免这个问题?
我会在您的域中引入一个名为 BookingDraft
的实体,您正在其中建立一个预订,但它还不是一个功能齐全的预订。
这个实体应该有自己的唯一 ID,它将进入 URL。如果您要将此草稿实体保存到数据库,它还应该包含用户 ID。
export interface BookingDraft {
// Unique identifier for this draft, such as a GUID. Can be persisted to a database, API, or to localStorage. This should go in the URL.
id:string;
userId:string;
hotelId?:string;
roomId?:string;
checkIn?:Date;
checkOut?:Date;
sessionId?:string;
}
然后,您的路线中将包含预订 ID,后跟该步骤的分段。
/create-booking/{bookingDraftId}/select-hotel
/create-booking/{bookingDraftId}/select-room
/create-booking/{bookingDraftId}/payment
您可以在每个段的路线中添加守卫或某种验证逻辑,以确保在用户尝试 select 房间之前草稿已经 hotelId
:
const routes: Routes = [
{
path: 'create-booking/:bookingDraftId',
children: [
{
path: 'select-hotel',
component: SelectHotelPageComponent
},
{
path: 'select-room',
component: SelectRoomPageComponent,
canActivate: [HotelSelectedGuard]
},
]
}
]
export class HotelSelectedGuard implements CanActivate {
constructor(private bookingDraftService: BookingDraftService, private router: Router) {}
public canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean|UrlTree> {
const draftId = next.paramMap.get('bookingDraftId');
return this.bookingDraftService
.getDraft(draftId)
.pipe(map(draft => {
if(!!draft.hotelId) {
return true;
}
return this.router.createUrlTree(['create-booking',draftId,'select-hotel'], {
queryParams: {
message: 'Please select a hotel before selecting a room'
}
})
}))
}
}
创建一个 BookingDraftService
来保存和检索往返于 localStorage
或一些 API 的预订汇票。
在我的酒店预订应用程序中,它由多个阶段组成,例如 Hotel Search -> Select Hotel -> Select Room -> Payment 和每个阶段有不同的页面。所有阶段都需要来自前一阶段的许多输入(在某些情况下大约 5-8 个),例如会话 ID、签入、签出等。我使用查询参数进行应用内导航,因为当用户刷新页面时它不应该中断。
我面临的问题是,太多的字段使 URL 变得丑陋,并且 nginx 在某些阶段也会因为 URL 大而抛出错误。我曾尝试将这些数据存储在服务中,但它没有帮助,因为刷新页面时数据丢失并且存储在 localStorage
中看起来不太好。那么,在这里我可以采取什么正确或最佳方法来避免这个问题?
我会在您的域中引入一个名为 BookingDraft
的实体,您正在其中建立一个预订,但它还不是一个功能齐全的预订。
这个实体应该有自己的唯一 ID,它将进入 URL。如果您要将此草稿实体保存到数据库,它还应该包含用户 ID。
export interface BookingDraft {
// Unique identifier for this draft, such as a GUID. Can be persisted to a database, API, or to localStorage. This should go in the URL.
id:string;
userId:string;
hotelId?:string;
roomId?:string;
checkIn?:Date;
checkOut?:Date;
sessionId?:string;
}
然后,您的路线中将包含预订 ID,后跟该步骤的分段。
/create-booking/{bookingDraftId}/select-hotel
/create-booking/{bookingDraftId}/select-room
/create-booking/{bookingDraftId}/payment
您可以在每个段的路线中添加守卫或某种验证逻辑,以确保在用户尝试 select 房间之前草稿已经 hotelId
:
const routes: Routes = [
{
path: 'create-booking/:bookingDraftId',
children: [
{
path: 'select-hotel',
component: SelectHotelPageComponent
},
{
path: 'select-room',
component: SelectRoomPageComponent,
canActivate: [HotelSelectedGuard]
},
]
}
]
export class HotelSelectedGuard implements CanActivate {
constructor(private bookingDraftService: BookingDraftService, private router: Router) {}
public canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean|UrlTree> {
const draftId = next.paramMap.get('bookingDraftId');
return this.bookingDraftService
.getDraft(draftId)
.pipe(map(draft => {
if(!!draft.hotelId) {
return true;
}
return this.router.createUrlTree(['create-booking',draftId,'select-hotel'], {
queryParams: {
message: 'Please select a hotel before selecting a room'
}
})
}))
}
}
创建一个 BookingDraftService
来保存和检索往返于 localStorage
或一些 API 的预订汇票。