首页 > 解决方案 > 在应用内导航时将数据传递到子路由,或在直接导航时使用解析器

问题描述

我有两个组件,一个费用报告组件和一个历史费用组件。路线如下所示:

expenses/:idExpenseReportComponent并调出显示该特定费用报告的视图。 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>

标签: angularangular-router

解决方案


推荐阅读