我正在尝试了解如何动态地将路由添加到来自延迟加载模块的路由。
我有核心应用,包含路线:
export const routes = [{
path: "",
component: HomeComponent
}, {
path: "moduleA",
loadChildren: "app/moduleA/A.module"
}];
在A.module中,我从“本地”模块A.routes.config.ts导入路由:
const routes = [{
path: "",
component: ModuleAHomeComponent,
children: [
{ path: "", component: ModuleAListComponent },
{ path: ":id", component: ModuleADetailComponent }
]
}];
export const routing = RouterModule.forChild(routes);
到现在为止还挺好。现在,在ModuleADetailComponent中,我有一个用于Web应用程序的“其他模块”列表,我将其称为插件,这些模块是单独开发的,并且我希望能够在ModuleADetailComponent页面中显示。
因此,此组件的模板如下所示:
<div *ngFor="let plugin of plugins">
<div class="header">{{ plugin.name }}</div>
<router-outlet name="*plugin.name*">*LOAD MODULE HERE*</router-outlet>
</div>
当然,插件是在导航到ModuleADetailComponent时加载的配置,因此我无法提前知道配置了哪些模块以及有多少个模块。
最后,每个插件都可以是NgModule(在工作台环境中单独开发)。
我需要的是:如何动态修改路由器配置,以将子级添加到moduleA.routes.config.ts中定义的路由?
例如,如果我有2个插件,我想动态地使用router.resetConfig来获得moduleA.routes.config.ts像这样的东西:
const routes = [{
path: "",
component: ModuleAHomeComponent,
children: [
{ path: "", component: ModuleAListComponent },
{
path: ":id",
component: ModuleADetailComponent,
children: [
{
path: "plugin1",
loadChildren: "app/plugins/plugin1.module",
outlet: "plugin1"
},
{
path: "plugin2",
loadChildren: "app/plugins/plugin2.module",
outlet: "plugin2"
}
]
}
]
}];
export const routing = RouterModule.forChild(routes);
我希望我能实现它,否则插件将不得不在没有路由的情况下进行开发...但是它们可以成为大型子模块,而这将从导航中受益。
编辑27/09/2016 :我已经组装了这个plunkr:http://plnkr.co/edit/6aV5n5K5wdqdiYo49lZv。
我目前能够做的是动态加载组件并将其添加到应用程序中(请参见“动态模块”选项卡)。
尽管没有找到任何官方文档,我仍然要做的是使用多个命名的路由器 socket (请参见“动态路由”选项卡)。尽管有标签名称,但路线是提前知道的。
我要做的是:动态加载配置(DynamicRoutesComponent中的dynamicRoutes数组),并且仅在为每个动态路由创建一个路由器导出并使用resetConfig(或它需要的东西)后才能具有此配置:
{
path: "dynamic-routed",
component: DynamicRoutesComponent,
children: [
{ path: "", component: EmptyComponent },
{ path: "component1", component: Component1, outlet: "component1" },
{ path: "component2", component: Component2, outlet: "component2" }
]
}
每条动态路线有一个 child 。
提前致谢!
最佳答案
首先,必须以以下格式(https://angular.io/docs/ts/latest/guide/router.html#!#asynchronous-routing)提供loadChildren
属性方法:
{
path: 'admin',
loadChildren: 'app/admin/admin.module#AdminModule',
},
如上所示,
module path
和module name
与#
char结合在一起。在您的情况下,您需要按以下方式或多或少地修改app.routes(不确定模块/文件名,而plunkr示例不能反射(reflect)此问题中给出的名称):
export const routes = [{
path: "",
component: HomeComponent
}, {
path: "moduleA",
loadChildren: "app/moduleA#ModuleA"
}];
这只是一个介绍,现在让我们继续解决您的问题。据我所读,您想动态添加子路由。
您可以使用以下代码在功能部件模块中动态提供子路线。
import {ROUTES} from '@angular/router/src/router_config_loader';
import {ANALYZE_FOR_ENTRY_COMPONENTS} from '@angular/core';
[...]
let routesToAdd = ... // provide your routes here
@NgModule({
[...]
imports: [RouterModule.forChild([])] // Empty on purpose
[...]
providers: [
{
provide: ROUTES,
useValue: routesToAdd,
multi: true
},
{
provide: ANALYZE_FOR_ENTRY_COMPONENTS,
useValue: routesToAdd, // provide them here too
multi: true
}
],
[...]
})
您必须为
ANALYZE_FOR_ENTRY_COMPONENTS
token (以及ROUTES
token )提供相同的路由,否则会收到No component factory found for YOUR_COMPONENT. Did you add it to @NgModule.entryComponents?
错误。但是,此代码可能会在AoT编译期间产生错误。在这种情况下,您需要提供
factory
代替value
token 的ROUTES
。但是,您将无法为factory
token 提供ANALYZE_FOR_ENTRY_COMPONENTS
-它仅接受useValue
(请参阅https://github.com/angular/angular/blob/03e855ae8f9e9b86251320c7551a96092bd8b0c4/modules/%40angular/compiler/src/metadata_resolver.ts#L926)。在这种情况下,请在功能模块上使用以下代码:
import {ROUTES} from '@angular/router/src/router_config_loader';
[...]
let routesToAdd = ... // provide your routes here
@NgModule({
[...]
imports: [RouterModule.forChild([])] // Empty on purpose
[...]
providers: [
{
provide: ROUTES,
useFactory: (getRoutesFromSomewhere),
//deps: [SomeService, SOME_TOKEN] // deps is optional, in the case you need no params - delete it; otherwise pass 'em
multi: true
}
],
entryComponents: [CompA, CompB, CompC, etc...]
[...]
})
注意:使用Observables/Promises提供路由不是可靠的解决方案,因此Angular路由器希望使用
Route[]
或Routes
,但是HTTP请求只能返回Observable/Promise(Angular应用程序已初始化,但是路由的检索过程仍然继续使用Observables/Promises)(请参阅https://github.com/ngx-i18n-router/config-loader#readme)。使用返回
Route[]
或Routes
的函数。同时,您可以检查module file(用于Angular的国际化实用程序,得益于动态路由)的@ngx-i18n-router/core,并将此example-app作为其实现。
关于dynamic - Angular 2(最终版): resetConfig to add routes to lazy loaded routes,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39572777/