angular - 在应用内导航时将数据传递到子路由,或在直接导航时使用解析器
问题描述
我有两个组件,一个费用报告组件和一个历史费用组件。路线如下所示:
expenses/:id
,ExpenseReportComponent
并调出显示该特定费用报告的视图。
expenses/:id/historical
对于HistoricalExpensesComponent
, 并且是上述的子路由。这会显示一个视图,显示该报告的员工的历史费用(由员工 ID 驱动)。请注意,员工 ID 不等于费用 ID,员工 ID 是从费用 ID 派生的。
当有人加载时expenses/:id
,我们会获取有关该费用报告的数据,包括候选人 ID。当有人加载时expenses/:id/historical
,我们有一个解析器,它会自动获取报告数据,并使用员工 ID 进行解析(这是组件需要运行的)。
这就提出了一个问题:从父控制器导航到子控制器时,如何避免子解析器中的此 API 调用。显然,因为我们在父控制器中,我们已经有了子控制器所需的employeeID,但我不知道如何将这些数据传递给导航。
原来解决方案是使用状态。我将状态上的employeeID 设置为来自父级的路由器链接的一部分。在解析器中,我检查该状态 - 如果它存在,我立即返回它,如果它不存在(有人直接导航到子路由,或刷新页面),那么我们得到 api。
我很好奇这是否是最佳实践,或者我是否错过了一些明显的东西?我知道我们可以通过多种方式来完成这项工作(比如使用服务)。这样做的想法是,子组件将始终从任何路由获取它的数据,因此它不需要知道任何其他内容,除了“检查路由器解析我的内容的数据”。这种方法是否容易出现我忽略的一些问题?花了一个小时才想出解决方案(本来会更快,但我们最初无法弄清楚如何在解析器中访问状态。)
代码示例:
// Routes
{
path: 'expenses/:id',
children: [
{ path: '', component: ExpenseReportComponent, pathMatch: 'full' },
{
path: 'historical',
component: HistoricalExpensesComponent,
resolve: {
"candidateId": ExpenseCandidateResolver
}
},
]
},
// Resolver
@Injectable({
providedIn: "root"
})
export class ExpenseCandidateResolver implements Resolve<any> {
constructor(private _http: HttpClient, private router: Router) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const candidate = this.router.getCurrentNavigation().extras?.state?.candidate;
// if state exists and has a candidate ID, immiiately resolve with that
if (candidate) {
return candidate;
}
// otherwise get the candiate via api
return this._http.get<any>("http://localhost:33333/api/report/" + route.params.id)
.toPromise()
.then(data => {
return data.CandidateID;
})
// todo: handle error
}
}
<!-- Link to navigate within the parent controller -->
<a routerLink="historical" [state]="{ candidate: Report.CandidateID }">Historical</a>
解决方案
推荐阅读
- node.js - 使用 axios 拦截器重试请求并将响应转发回前端
- javascript - 如何在 Javascript 的 REGEX 中将搜索结果限制为一次
- python - 在 MongoDB、Python、HTML 和 Ajax 方面需要帮助
- flutter - Flutter 展开 Row 并将子代与水平 SingleChildScrollView 内的 spaceBetween 对齐
- excel - 如何根据第一个单元格是否为空有条件地格式化 Excel VBA 中的一行?
- javascript - 如何在反应setState中交换两个变量
- python - argparse的非常基本的例子?
- python - 如何正确设置python计数器?当前的逻辑有什么问题?
- unreal-engine4 - 如何根据文本大小获取文本大小或调整小部件的大小?
- javascript - React.createElement:类型无效,尽管导入/导出不应该是错误的