角卫,文档中的陈述不清楚

时间:2017-07-10 07:20:06

标签: angular angular2-routing guard

我正在努力深入了解角度,所以我读了the docs,这非常有帮助 现在我正在研究守卫。我在文档中读到了这个陈述。

  

路由器首先检查CanDeactivate和CanActivateChild防护,从最深的子路由到顶部。然后它从上到下检查CanActivate警卫到最深的子路线。

现在我很困惑,为什么角度以这种方式表现呢? 对于 CanDeactivate &amp ;;从最深的孩子到顶部进行检查是否有任何好处?的 CanActivateChild 即可。从 CanActivate 到最深的儿童路线?

2 个答案:

答案 0 :(得分:14)

我曾试图相信文档网站上的内容。但是,它似乎并不完全正确,或者实施已更新但文档无法更新。

简要说明:

首先,从最深层检查CanDeactivate防护,并从从最顶层检查{/ 1}}防护(它将退出,在遍历中使用falsy check。)

其次,不会从最深层检查CanActivate警卫。

TL; DR

详细说明

我们应该查看来源以了解它是如何工作的。

  

注意:检查的提交是:https://github.com/angular/angular/tree/edb8375a5ff15d77709ccf1759efb14091fa86a4

第1步 - 查看何时调用CanActivateChild

source here L929

这只是调用其优秀来电者CanActivateChild的地方。

在那一行,我们可以得到一些暗示它与runCanActivateChild做同样的技巧,因为CanActivate的高级调用者CanActivate被调用。

第2步 - 了解runCanActivate如何运作

L926L950

runCanActivateChild的迭代中调用了{p> runCanActivateChild,与调用canActivateChecks的方式相同。我们知道runCanActivate(我的意思是该功能)和CanActivate共享相同的数据源 - CanActivateChild

第3步 - 什么是canActivateChecks以及如何处理

那么,canActivateChecks是什么?显然,我们可以发现它是canActivateChecks类实例的数组。但是如何分配CanActivateGo to here L865。这是重要的部分,所以我将它们粘贴在这里。

canActivateChecks

有点长。但是如果你经历它,你会发现它会播放深度优先遍历。让我们忽略相同的路由切换。查找 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, currNode, 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, context ? context.children : null, futurePath); // if we have a componentless route, we recurse but keep the same outlet map. } else { this.traverseChildRoutes(futureNode, null, parentContexts, futurePath); } } } 并查看主要步骤。它显示它首先更新##### comment by e-cloud #####然后执行下一级别的travesal(整个预订遍历)。

您必须知道路由器会将应用的所有路由视为网址树。每个canActivateChecks通过遍历将其PreActivation(作为树路径)拆分为路径段

采用简化示例:

  

我们的未来路线为future   然后我们会得到[&#39; / a&#39;,&#39; / a / b&#39;,&#39; / a / b / c&#39; ] /a/b/c

显然,canActivateChecks代表canActivateChecks从最顶层到最深层的路线 源代码显示future从左到右迭代。

第4步 - 结论

我们可以得出结论,canActivateChecks是从最顶层到最深的孩子。

希望我能清楚地解释清楚。

答案 1 :(得分:4)

当你考虑路由时,你去的树越深,你获得的具体越多。

例如:

/food-types/sweets/pies/blueberry

因此,当您告诉Angular您希望离开blueberry饼时,它首先会检查蓝莓上的CanDeactivate,因为您正在向上返回导航树,到另一个位置。根据我的理解,CanActivateChild也会走到树的路径上,出于同样的原因:它想先检查最深层次,以验证他们的孩子是否可以被激活。

CanActivate相反。当你告诉Angular你想要看到blueberry馅饼时,你正沿着树走下去,因此,当它沿着树走下去的时候,它会检查卫兵。