首页 > 解决方案 > 如何在 Angular 中处理大的 URL 参数

问题描述

在我的酒店预订应用程序中,它包含多个阶段,例如酒店搜索 -> 选择酒店 -> 选择房间 -> 付款,每个阶段都有不同的页面。所有阶段都需要前一阶段的许多输入(在某些情况下大约 5-8 个),如 session-id、签入、签出等。我正在使用 Query Params 进行应用内导航,因为当用户刷新页面时它不应该中断。

我面临的问题是,太多的字段使 URL 变得丑陋,而且由于 URL 很大,nginx 在某些阶段也会抛出错误。我曾尝试将这些数据存储在服务中,但它没有帮助,因为刷新页面时数据丢失并且存储在其中localStorage看起来并不好。那么,我可以在这里采取什么正确或最好的方法来避免这个问题呢?

标签: angularangular8angular-routingquery-parameters

解决方案


我会在您的域中引入一个名为 的实体,BookingDraft您正在其中建立预订,但它还不是功能齐全的预订。

该实体应该有自己的唯一 ID,该 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

您可以为每个段的路线添加保护或某种验证逻辑,以确保草稿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 的预订草稿。


推荐阅读