角卫,文档中的陈述不清楚
我正在努力深入了解角度,所以我读了
the docs,这非常有帮助。
现在我正在研究守卫。我在文档中读到了这个陈述。
现在我很困惑,为什么角度以这种方式表现呢?
我试图相信文档网站上写的内容。但是,它似乎并不完全正确,或者实施已更新,但文档不会更新。
简要说明: 首先,从最深到最顶层检查CanDeactivate防护,并从顶部到最深处检查CanActivate防护(它将在遍历中退出并进行错误检查)。 其次,CanActivateChild守卫不会从最深层到最高层进行检查。 TL; DR 详细说明 我们应该查看源代码,看看它是如何工作的。
第1步 – 查看CanActivateChild何时被调用 source here L929。 这只是其高级调用者runCanActivateChild被调用的地方。 在那一行,我们可以得到一些暗示它与CanActivate做同样的技巧,因为CanActivate的优秀调用者runCanActivate被调用。 第2步 – 看看runCanActivateChild是如何工作的 L926和L950。 runCanActivateChild在canActivateChecks的迭代中被调用,与调用runCanActivate的方式相同。在这里,我们知道CanActivate(我的意思是该功能)和CanActivateChild共享相同的数据源 – canActivateChecks。 第3步 – 什么是canActivateChecks以及如何处理它 那么,什么是canActivateChecks?显然,我们可以发现它是CanActivate类实例的数组。但是如何分配canActivateChecks? Go to here L865.这是重要的部分,所以我打算将它们粘贴在这里。 private traverseChildRoutes( futureNode: TreeNode<ActivatedRouteSnapshot>,currNode: TreeNode<ActivatedRouteSnapshot>|null,contexts: ChildrenOutletContexts|null,futurePath: ActivatedRouteSnapshot[]): void { const prevChildren = nodeChildrenAsMap(currNode); // Process the children of the future route futureNode.children.forEach(c => { this.traverseRoutes(c,prevChildren[c.value.outlet],contexts,futurePath.concat([c.value])); delete prevChildren[c.value.outlet]; }); // Process any children left from the current route (not active for the future route) forEach( prevChildren,(v: TreeNode<ActivatedRouteSnapshot>,k: string) => this.deactivateRouteAndItsChildren(v,contexts !.getContext(k))); } private traverseRoutes( futureNode: TreeNode<ActivatedRouteSnapshot>,currNode: TreeNode<ActivatedRouteSnapshot>,parentContexts: ChildrenOutletContexts|null,futurePath: ActivatedRouteSnapshot[]): void { const future = futureNode.value; const curr = currNode ? currNode.value : null; const context = parentContexts ? parentContexts.getContext(futureNode.value.outlet) : null; // reusing the node if (curr && future._routeConfig === curr._routeConfig) { if (this.shouldRunGuardsAndResolvers( curr,future,future._routeConfig !.runGuardsAndResolvers)) { this.canActivateChecks.push(new CanActivate(futurePath)); const outlet = context !.outlet !; this.canDeactivateChecks.push(new CanDeactivate(outlet.component,curr)); } else { // we need to set the data future.data = curr.data; future._resolvedData = curr._resolvedData; } // If we have a component,we need to go through an outlet. if (future.component) { this.traverseChildRoutes( futureNode,currNode,context ? context.children : null,futurePath); // if we have a componentless route,we recurse but keep the same outlet map. } else { this.traverseChildRoutes(futureNode,parentContexts,futurePath); } } else { // ##### comment by e-cloud ##### if (curr) { this.deactivateRouteAndItsChildren(currNode,context); } this.canActivateChecks.push(new CanActivate(futurePath)); // If we have a component,we need to go through an outlet. if (future.component) { this.traverseChildRoutes(futureNode,null,futurePath); } } } 这有点长。但是如果你经历它,你会发现它会进行深度优先遍历。让我们忽略相同的路由切换。通过e-cloud #####查找#####评论并查看主要程序。它显示它首先更新canActivateChecks然后执行下一级别的travesal(整个预订遍历)。 您必须知道路由器将应用程序的所有路由视为URL树。每个PreActivation通过遍历将其未来(作为树路径)分成路径段。 举个简单的例子:
显然,canActivateChecks代表了从最高层到最深层的路线 第4步 – 结论 我们可以得出结论,CanActivateChild是从最顶层到最深的孩子。 希望我能清楚地解释清楚。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |