- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我试图深入理解 Angular,所以我阅读了 the docs这非常有帮助。
现在我正在研究守卫。我在文档中阅读了此声明。
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,从最深的 child 到顶部进行检查有什么好处。以及从顶部到最深的 CanActivate 子路由?
最佳答案
我曾试图相信文档站点中所写的内容。但是,它似乎并不完全正确,或者实现已更新但文档没有更新。
简而言之:
首先,CanDeactivate
守卫从最深到顶部检查,CanActivate
守卫从从顶部到最深检查(它将退出并在遍历中进行虚假检查)。
其次,CanActivateChild
守卫不会从最深到最顶部进行检查。
长话短说
我们应该检查源代码以了解它是如何工作的。
Note: the commit checked is: https://github.com/angular/angular/tree/edb8375a5ff15d77709ccf1759efb14091fa86a4
CanActivateChild
何时被调用这只是它的上级调用者 runCanActivateChild
被调用的地方。
在那一行,我们可以得到一些提示,它与 CanActivate
有相同的技巧,因为 CanActivate
的高级调用者 runCanActivate
是之后调用。
runCanActivateChild
是如何工作的runCanActivateChild
在 canActivateChecks
的迭代中被调用,与 runCanActivate
的调用方式相同。这里我们知道 CanActivate
(我指的是功能)和 CanActivateChild
共享相同的数据源 -- canActivateChecks
。
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, 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);
}
}
}
有点长。但是如果你仔细研究它,你会发现它在进行深度优先遍历。让我们忽略相同的路由切换。找到#####易云评论#####
,查看主要流程。它表明它首先更新canActivateChecks
,然后执行下一级遍历(整体为前序遍历)。
你必须知道路由器将应用程序的所有路由视为一个 url 树。每个 PreActivation
通过遍历将其 future
(作为树路径)分成路径段。
举一个简化的例子:
we have the future route as
/a/b/c
.
Then we will get [ '/a', '/a/b', '/a/b/c' ] ascanActivateChecks
显然,canActivateChecks
代表了 future
从顶部到最深处的路线源代码显示 canActivateChecks
从左到右迭代。
我们可以得出结论,CanActivateChild
是从顶部到最深的 child 运行的。
希望我解释清楚。
关于Angular 守卫,文档中的陈述不明确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45005949/
我在 linux 上工作。我对windows没有太多想法。 windows中文件的权限是如何组织的?我们在unix中是否有像chmod这样的api来更改权限? 最佳答案 对于 Windows,有一个名
应用程序编程接口(interface) (API) 是一组用于访问基于 Web 的软件应用程序的编程指令和标准。 如果出现 ,有人可以向我解释一下吗?谷歌地图 或 优酷 这是API哪个是softwar
我有两个应用程序,A 和 B,它们使用 android 库 C。B 有一个服务 A 想通过 C 使用,例如 在我的库中有一个类试图将它绑定(bind)到服务,
我正在正常或安全模式下启动相机应用程序,具体取决于使用我的应用程序执行的手势,但一旦用户选择应用程序并点击始终,则没有选项可以更改默认值,即使是从 Android 的设置菜单中也是如此. camera
我有一个数据集,本质上是一个稀疏二进制矩阵,表示两个集合的元素之间的关系。例如,让第一组是人(用他们的名字表示),例如像这样的东西: people = set(['john','jane','mike
何为pythonic? pythonic如果翻译成中文的话就是很python。很+名词结构的用法在中国不少,比如:很娘,很国足,很CCTV等等。 我的理解为,很+名词表达了一种特殊和强调的意味。
某些 Prolog 目标的确定性成功问题已经一次又一次地出现在 - 至少 - 以下问题: Reification of term equality/inequality Intersection an
我指的是 DateTime.TryParse(string s, out DateTime result) 重载,它尝试从字符串中解析 DateTime - 没有特定的格式正在指定。 我可以从http
2020 年 04 月 10 日,《中共中央国务院关于构建更加完善的要素市场化配置体制机制的意见》正式公布,将数据确立为五大生产要素(土地、资本、劳动力以及技术)之
有人可以解释一下 NSNotification 的 addObserver 函数中 notificationSender 的用途吗? 这是 Apple 文档的解释: notificationSende
我是一名优秀的程序员,十分优秀!