我想配置我的 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”未定义。有人可以帮我解决这个问题吗?
您几乎拥有正确的代码,但您错过了this.fetchListsAndIDs()执行异步 observable 的部分,因此您的if..else块甚至在 API 调用完成之前就已执行。
this.fetchListsAndIDs()
if..else
我建议您if...else在处理程序中包含检查next()。我已经颠倒了条件以首先检查 NOT,因为您已经在details.components.ts其中代表 /groups/lists/${listID}/details路由,如果 id 无效,)您应该只将用户重定向回,否则组件lists应继续其工作。
if...else
next()
details.components.ts
)
lists
我添加了代码来获取listId来自 URL。您在问题中发布的代码中缺少它。
listId
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 } }