对 Angular 多个空路径的路由器逻辑感到困惑
Confusion about Angular Router logic for multiple empty paths
在学习 Angular 路由器的工作原理时,我遇到了一些我不太理解的令人费解的行为。似乎如果你有一个这样的路由配置设置(延迟加载的模块每个都有自己的路由配置,只包含一个空路径和一个组件:
export const appRoutes: Routes = [
{ path: "", component: DefaultComponent },
{ path: "", loadChildren: "./module-one/module-one.module#ModuleOne" },
{ path: "two", loadChildren: "./module-two/module-two.module#ModuleTwo" },
{ path: "three", loadChildren: "./module-three/module-three.module#ModuleThree" },
{ path: "one", loadChildren: "./module-one/module-one.module#ModuleOne" },
]
然后导航到 /two
,然后将创建 ModuleOne
,然后将创建 ModuleTwo
,最后是 ModuleTwo
创建的 SecondComponent
将被创建。但是,ModuleOne
应该创建的组件没有创建。
1) 为什么要创建 ModuleOne
,为什么要先创建?
2) 为什么 ModuleOne
没有创建它的组件?
2) 为什么 Router
选择第二个空路径而不是第一个?
我想我明白为什么要创建 ModuleOne
(以及为什么先创建)。文档说空路径不会消耗任何 url 段,所以我猜想当路由器找到空路径时,它会执行空路径应该做的任何事情,然后开始重新解析 url树从哪里找到空路径? (不是 100% 关于这种行为)。这并不能解释为什么它忽略了加载 DefaultComponent
的空路径。
另一个奇怪的是,当第二条空路径的路由被注释掉时:
//{ path: "", loadChildren: "./module-one/module-one.module#ModuleOne" },
我们只剩下一条通往 DefaultComponent
的空路径,当导航到 /two
时,该路径永远不会被触发,即使另一条空路径触发了。文档中有什么明显的东西我没有注意到吗?
这是一个 StackBlitz,看看我在说什么 https://stackblitz.com/edit/angular-gitter-o5tttb
我在 Router
中启用了跟踪,这就是我知道 modules/components 创建了什么的方式。
当您导航到two
时,路由器开始一条一条地处理路由。所以它从第一个开始:
{ path: "", component: DefaultComponent },
它匹配为空字符串总是匹配。然后剩余的段是 two
并且路由器尝试查找当前正在处理的路由是否具有路径为 two
的子路由。此路由没有任何子路由,因此路由器将其丢弃。
然后转到第二条路线:
{ path: "", loadChildren: "./module-one/module-one.module#ModuleOne" },
同样,它是一个空字符串路由,所以它匹配。现在,为了让路由器检查是否有任何子路由与剩余的段 two
匹配,它需要获取该路由。一旦模块被获取,它应该被编译和实例化,因为它使用 RouterModule.forChild(moduleOneRoutes)
定义新路由。创建模块后,路由器获取路由并发现只有一条路由为空路径,并且与剩余的段 two
不匹配。路线被拒绝。
然后进入第三条路线:
{ path: "two", loadChildren: "./module-two/module-two.module#ModuleTwo" }
它完全匹配段,因此它获取模块并实例化它带来的组件。
在学习 Angular 路由器的工作原理时,我遇到了一些我不太理解的令人费解的行为。似乎如果你有一个这样的路由配置设置(延迟加载的模块每个都有自己的路由配置,只包含一个空路径和一个组件:
export const appRoutes: Routes = [
{ path: "", component: DefaultComponent },
{ path: "", loadChildren: "./module-one/module-one.module#ModuleOne" },
{ path: "two", loadChildren: "./module-two/module-two.module#ModuleTwo" },
{ path: "three", loadChildren: "./module-three/module-three.module#ModuleThree" },
{ path: "one", loadChildren: "./module-one/module-one.module#ModuleOne" },
]
然后导航到 /two
,然后将创建 ModuleOne
,然后将创建 ModuleTwo
,最后是 ModuleTwo
创建的 SecondComponent
将被创建。但是,ModuleOne
应该创建的组件没有创建。
1) 为什么要创建
ModuleOne
,为什么要先创建?2) 为什么
ModuleOne
没有创建它的组件?2) 为什么
Router
选择第二个空路径而不是第一个?
我想我明白为什么要创建 ModuleOne
(以及为什么先创建)。文档说空路径不会消耗任何 url 段,所以我猜想当路由器找到空路径时,它会执行空路径应该做的任何事情,然后开始重新解析 url树从哪里找到空路径? (不是 100% 关于这种行为)。这并不能解释为什么它忽略了加载 DefaultComponent
的空路径。
另一个奇怪的是,当第二条空路径的路由被注释掉时:
//{ path: "", loadChildren: "./module-one/module-one.module#ModuleOne" },
我们只剩下一条通往 DefaultComponent
的空路径,当导航到 /two
时,该路径永远不会被触发,即使另一条空路径触发了。文档中有什么明显的东西我没有注意到吗?
这是一个 StackBlitz,看看我在说什么 https://stackblitz.com/edit/angular-gitter-o5tttb
我在 Router
中启用了跟踪,这就是我知道 modules/components 创建了什么的方式。
当您导航到two
时,路由器开始一条一条地处理路由。所以它从第一个开始:
{ path: "", component: DefaultComponent },
它匹配为空字符串总是匹配。然后剩余的段是 two
并且路由器尝试查找当前正在处理的路由是否具有路径为 two
的子路由。此路由没有任何子路由,因此路由器将其丢弃。
然后转到第二条路线:
{ path: "", loadChildren: "./module-one/module-one.module#ModuleOne" },
同样,它是一个空字符串路由,所以它匹配。现在,为了让路由器检查是否有任何子路由与剩余的段 two
匹配,它需要获取该路由。一旦模块被获取,它应该被编译和实例化,因为它使用 RouterModule.forChild(moduleOneRoutes)
定义新路由。创建模块后,路由器获取路由并发现只有一条路由为空路径,并且与剩余的段 two
不匹配。路线被拒绝。
然后进入第三条路线:
{ path: "two", loadChildren: "./module-two/module-two.module#ModuleTwo" }
它完全匹配段,因此它获取模块并实例化它带来的组件。