我正在尝试了解如何动态地将路由添加到延迟加载的模块中。 我有核心应用程序,路线:
export const routes = [{
path: "",
component: HomeComponent
}, {
path: "moduleA",
loadChildren: "app/moduleA/A.module"
}];
在A.module中我从“local”moduleA.routes.config.ts导入路由:
const routes = [{
path: "",
component: ModuleAHomeComponent,
children: [
{ path: "", component: ModuleAListComponent },
{ path: ":id", component: ModuleADetailComponent }
]
}];
export const routing = RouterModule.forChild(routes);
到目前为止一切顺利。现在,在ModuleADetailComponent中,我有一个“附加模块”列表,我将其称为插件,用于我的webapp,它们是单独开发的,我希望能够在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);
我希望我能实现它,否则插件必须在没有路由的情况下开发......但它们可以成为可以从导航中受益的大型子模块。
编辑2016年9月27日:我收集了这个傻瓜:http://plnkr.co/edit/6aV5n5K5wdqdiYo49lZv。 我目前能够做的是动态加载组件并将它们添加到应用程序(请参见“动态模块”选项卡)。 我还做的是使用多个命名路由器插座,尽管没有找到任何官方文档(请参阅“动态路由”选项卡)。尽管有标签名称,但提前知道路线。
我想要做的是:动态加载配置(DynamicRoutesComponent中的dynamicRoutes数组),并且只有在每个动态路由创建一个路由器出口并使用resetConfig(或它需要什么)才能进行此配置:
{
path: "dynamic-routed",
component: DynamicRoutesComponent,
children: [
{ path: "", component: EmptyComponent },
{ path: "component1", component: Component1, outlet: "component1" },
{ path: "component2", component: Component2, outlet: "component2" }
]
}
每个动态路线有一个孩子。
提前致谢!
答案 0 :(得分:5)
首先,必须使用以下格式(https://angular.io/docs/ts/latest/guide/router.html#!#asynchronous-routing)提供loadChildren
属性方法:
{
path: 'admin',
loadChildren: 'app/admin/admin.module#AdminModule',
},
如上所述,module path
和module name
与#
字符一起加入。
在您的情况下,您需要或多或少地修改您的app.routes如下(不确定您的模块/文件名,并且plunkr示例不反映此问题中给出的名称):
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
令牌(以及ROUTES
令牌)提供相同的路由,否则您将收到No component factory found for YOUR_COMPONENT. Did you add it to @NgModule.entryComponents?
错误。
但是,此代码可能会在AoT编译期间产生错误。在这种情况下,您需要为factory
令牌提供value
而不是ROUTES
。但是,您无法为factory
令牌提供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的@ngx-i18n-router/core(Angular的国际化实用程序,动态路由的好处)以及此example-app作为其实现。
答案 1 :(得分:0)
是否可以做类似this的事情?基本上,在组件的构造函数中,您可以访问activatedRoute.routeConfig.children
,使用它应该可以向该数组添加更多子项。
如果您尝试从其他来源获取数据,则应该能够在subscriber
的{{1}}部分中进行设置。我在想这样的事情:
Observable
答案 2 :(得分:0)
实际上,我遇到的问题是如何构建newChildRoute
:
在我有类似的东西之前:
"path": pathFromFile,
"outlet": outletFromFile,
"data": dataFromFile,
"component": HostComponent, (my custom host component for named outlet)
"loadChildren": moduleURLFromFile + "#" + moduleNameFromFile
创建新对象{}来更改我的实际this.router.config
。
以这种方式调用this.router.resetConfig(this.router.config);
应该可以。...
但要更换 “ loadChildren”:moduleURLFromFile +“#” + moduleNameFromFile
使用
“ loadChildren”:()=> import(moduleURLFromFile)。然后(m => m.moduleNameFromFile)
似乎不起作用。
希望可以更好地阐明