一尘不染

在导航到页面之前检查 URL 中的数据是否有效

javascript

我想配置我的 Angular 组件,以便仅在 URL 中的 ID 有效时才加载页面。这里的重点是,我想保护页面免受用户手动输入随机 URL 并访问任何页面的影响。

我有一个带有列表的组件。 零件

如果我单击“显示详细信息”,Angular 会导航到详细信息页面。如果输入的 URL 包含有效的 ID,我只想打开此页面。为此,我调用一个服务来将所有 ID 收集到一个字符串数组中。然后检查输入的 ID 是否是该数组的成员。

我试过的:

list.component.ts:

  ngOnInit() {
    this.fetchLists();
  }

  fetchLists() {
    from(this.listService.getGroups())
      .pipe(
        takeUntil(this.destroy$)
      )
      .subscribe({
        next: (listUI: ListUI[]) => {
          this.listData = listUI;
        },
        error: (error) => {
          this.logger.debug(error.message);
          this.certError = true;
        }
      });
  }

details.component.ts:

  ngOnInit() {
    this.fetchListsAndIDs();
    if (this.validIDsList.includes(listID)) {
      this.router.navigateByUrl(`/groups/lists/${listID}/details`);
    }
    else {this.router.navigateByUrl(`/groups/lists`);}
  }

  fetchListsAndIDs() {
    from(this.listService.getGroups())
      .pipe(
        takeUntil(this.destroy$)
      )
      .subscribe({
        next: (listUI: ListUI[]) => {
          const listData = listUI;
          this.validIDsList = listData.map((lists) => lists.id);
        },
        error: (error) => {
          this.logger.debug(error.message);
          this.certError = true;
        }
      });
  }

app.routing.module.ts

   {
    path: 'groups/lists/${listID}/details',
    component: DetailsComponent
   }

“groups/lists/99999999999/details”页面打开,数据为零,“this.validIDsList”未定义。有人可以帮我解决这个问题吗?


阅读 94

收藏
2022-07-26

共1个答案

一尘不染

您几乎拥有正确的代码,但您错过了this.fetchListsAndIDs()执行异步 observable 的部分,因此您的if..else块甚至在 API 调用完成之前就已执行。

我建议您if...else在处理程序中包含检查next()。我已经颠倒了条件以首先检查 NOT,因为您已经在details.components.ts其中代表 /groups/lists/${listID}/details路由,如果 id 无效,)您应该只将用户重定向回,否则组件lists应继续其工作。

我添加了代码来获取listId来自 URL。您在问题中发布的代码中缺少它。

 ngOnInit() {
    this.listID = this.route.snapshot.paramMap.get('listID');
    this.fetchListsAndIDs();
 }

  fetchListsAndIDs() {
    from(this.listService.getGroups())
      .pipe(
        takeUntil(this.destroy$)
      )
      .subscribe({
        next: (listUI: ListUI[]) => {
          const listData = listUI;
          this.validIDsList = listData.map((lists) => lists.id);
          this.handleNavigation();
        },
        error: (error) => {
          this.logger.debug(error.message);
          this.certError = true;
        }
      });
  }

  handleNavigation() {
     if (!this.validIDsList.includes(this.listID)) {
       this.router.navigateByUrl(`/groups/lists`);
     } else {
       // call the function to continue with details component
     }
  }
2022-07-26