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

Rae*_*laf 23 guard angular2-routing angular

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

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

现在我很困惑,为什么角度以这种方式执行它?
对于CanDeactivateCanActivateChild,从最深的孩子到顶部进行检查有什么好处.从顶部到CanActivate最深的儿童路线?

e-c*_*oud 14

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

简要说明:

首先,CanDeactivate警卫从检查最深的顶部CanActivate警卫检查,从顶部到最深处(它将退出与遍历falsy检查).

其次,CanActivateChild警卫不会从最深处到最高层进行检查.


TL; DR

详细说明

我们应该查看源代码,看看它是如何工作的.

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

第1步 - 看看何时CanActivateChild被召唤

来源L929.

这只是其优秀来电者runCanActivateChild被召唤的地方.

在那一行,我们可以得到一些暗示它做同样的伎俩CanActivate,因为之后CanActivate调用了优秀的调用者runCanActivate.

第2步 - 看看如何runCanActivateChild工作

L926L950.

runCanActivateChild在迭代中被调用canActivateChecks,与runCanActivate被调用的方式相同.在这里,我们知道CanActivate(我的意思是该功能)并CanActivateChild共享相同的数据源 - canActivateChecks.

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

那么,是什么canActivateChecks?显然,我们可以发现它是一个CanActivate类实例数组.但如何canActivateChecks分配?转到这里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, 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);
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

这有点长.但是如果你经历它,你会发现它会进行深度优先遍历.让我们忽略相同的路由切换.查找##### comment by e-cloud #####并查看主要步骤.它显示它更新第canActivateChecks一个然后执行下一个级别travesal(整个预订遍历).

您必须知道路由器将应用程序的所有路由视为URL树.每个通过遍历PreActivation将其future(作为树路径)分割成路径段.

举个简单的例子:

我们有未来的路线/a/b/c.
然后我们将['/ a','/ a/b','/ a/b/c']作为canActivateChecks

显然,canActivateChecks代表从顶部到最深处的路线future .源节目canActivateChecks从左到右迭代.

第4步 - 结论

我们可以得出结论,CanActivateChild从最顶层到最深的孩子.

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