警卫队,文档中的声明不明确 [英] Angular guards, unclear statement in the docs

查看:82
本文介绍了警卫队,文档中的声明不明确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图深入了解角度,因此我阅读了文档,它非常有帮助.
现在我正在研究警卫.我在文档中阅读了此声明.

I'm trying to understand angular deeply, so i read the docs and it was very helpful.
now i'm studying the guards. and i read this statement in the docs.

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

The router checks the CanDeactivate and CanActivateChild guards first, from the deepest child route to the top. Then it checks the CanActivate guards from the top down to the deepest child route.

现在我很困惑,为什么angular会以这种方式执行它?
从最深的孩子到最上层的孩子检查 CanDeactivate &有什么好处? CanActivateChild .并从顶部到最深的子路径进行 CanActivate ?

now i'm confused, why does angular perform it in this way?
is there any benefits of doing the checking from the deepest child to the top for CanDeactivate & CanActivateChild. and from top to the deepest child route for CanActivate?

推荐答案

我试图相信docs网站中的内容.但是,这似乎并不完全正确,或者实现已更新,但是文档没有更新.

I had tried to believe what have written in the docs site. However, it appears it's not totally right, or the implementation has been updated but docs doesn't update.

要简短:

首先,从最深至最深检查CanDeactivate防护,并从最深至最深检查CanActivate防护(将退出 >虚假检查遍历.

First, CanDeactivate guards are checked from deepest to top and CanActivate guards are checked from top to deepest(it will quit with falsy check in the traversal).

第二,CanActivateChild防护未从最深到最顶进行检查.

Second, CanActivateChild guards are not checked from deepest to top.

TL; DR

我们应该检查源代码以了解其工作原理.

we should check the source to see how it work.

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

步骤1-查看何时调用CanActivateChild

在此处获取L929 .

step 1 - see when CanActivateChild got called

source here L929.

这仅是其上级呼叫方runCanActivateChild被呼叫的地方.

This is only place its superior caller runCanActivateChild got called.

在那一行,我们可以得到一些提示,表明它的作用与CanActivate相同,因为CanActivate的上级调用方runCanActivate是在之后被调用的.

At that line, we can get some hint that it does the same trick as CanActivate, because CanActivate's superior caller runCanActivate is called after.

L926 L950 .

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

runCanActivateChild got called within the iteration of canActivateChecks, same as how runCanActivate got called. Here we know CanActivate(i mean the feature) and CanActivateChild share the same data source -- canActivateChecks.

那么,canActivateChecks是什么?显然,我们可以发现它是CanActivate类实例的数组.但是如何分配canActivateChecks? 转到此处L865 .这是重要的部分,所以我要在这里粘贴它们.

So, what is canActivateChecks? Obviously, We can find out it's an array of CanActivate class instances. But how is canActivateChecks got assigned? Go to here L865. This is the important part, so i am going to paste them here.

  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);
      }
    }
  }

有点长.但是,如果您经过它,就会发现它播放了 depth-first-traversal .让我们忽略相同的路由切换.找到##### comment by e-cloud #####并查看主要过程.它显示出它首先更新canActivateChecks然后执行下一级遍历(整体上是遍历遍历).

It's a little long. But If you go through it, you would figure out it plays a depth-first-traversal. Let's ignore the same route switching. Find ##### comment by e-cloud ##### and see the main procedure. It shows that it updates the canActivateChecks first then performs next level travesal(Pre-order traversal at whole).

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

You must know the router treats all the routes of the app as a url tree. Each PreActivation split its future(as a tree path) into path segments by the traversal.

以一个简化示例为例:

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

we have the future route as /a/b/c.
Then we will get [ '/a', '/a/b', '/a/b/c' ] as canActivateChecks

显然,canActivateChecks表示从future的顶部到最深处的路线 消息来源显示canActivateChecks从左向右迭代.

Apparently, canActivateChecks represents the routes from top to deepest of the future The source shows canActivateChecks is iterated from left to right.

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

we can conclude that CanActivateChild is run from top to deepest child.

希望我能清楚地解释它.

Hope i explain it clearly.

这篇关于警卫队,文档中的声明不明确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆