我已经创建了一个github存储库,它有一个完美的问题示例。
https://github.com/rjriel/dynamic-route-example
这个回购中代码的重要部分是在app.module.ts
let mainRoutes: Routes = [{
path: "first",
component: FirstComponent
}]
mainRoutes.push({
path: "second",
component: SecondComponent
})
@NgModule({
...
imports: [
RouterModule.forRoot(mainRoutes),
在开发中运行此代码(即.ng serve
)时,两个路由都正确导航。但是,在生产中运行此代码(即.ng serve --prod
)时,通过second
添加的mainRoutes.push
路由会导致以下错误:
ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL
Segment: 'second'
Error: Cannot match any routes. URL Segment: 'second'
at t.BkNc.t.noMatchError (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.selector (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at t.BkNc.t.noMatchError (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.selector (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e.error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.T14+.e._error (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at u (polyfills.8c1e4b56978ce6347832.bundle.js:1)
at u (polyfills.8c1e4b56978ce6347832.bundle.js:1)
at polyfills.8c1e4b56978ce6347832.bundle.js:1
at e.invokeTask (polyfills.8c1e4b56978ce6347832.bundle.js:1)
at Object.onInvokeTask (vendor.0828fd59ec5e6a599e72.bundle.js:1)
at e.invokeTask (polyfills.8c1e4b56978ce6347832.bundle.js:1)
at r.runTask (polyfills.8c1e4b56978ce6347832.bundle.js:1)
at o (polyfills.8c1e4b56978ce6347832.bundle.js:1)
at t.invokeTask [as invoke] (polyfills.8c1e4b56978ce6347832.bundle.js:1)
at h (polyfills.8c1e4b56978ce6347832.bundle.js:1)
是否有人碰巧知道为什么编译生产会产生这个错误,而它在开发中完全正常?或者至少是一种更好的调试方法?
编辑:
我在这里做的实际实现是我在一个网站上有多个页面,具有相同的信息布局,所以我创建了一个json文件,这是一个对象,其中每个键是路由,值是信息的路线。然后我加载json并添加路由,如下所示:
import * as PageLayouts from '../page-layouts.json'
import { MainLayoutComponent } from './main-layout/main-layout.component'
Object.keys(PageLayouts).forEach(key => {
mainRoutes.push({
path: key,
component: MainLayoutComponent
})
})
我在上面的forEach之后做一个console.log(mainRoutes)
并按预期看到数组中的所有路由。另外为了澄清,这个forEach
循环在@NgModule
声明之前完成,如示例代码所示。对于开发的JiT编译,这一切都完全正常,但是上面提到了AoT编译用于生产的问题。
简短的回答是,当您为生产编译时,它使用Ahead of Time(AOT)过程而不是Just in Time(JiT)过程。这就是为什么你会看到不同的结果。
你可以在这里阅读更多关于AOT的信息:https://angular.io/guide/aot-compiler
这篇文章可能会有所帮助:http://blog.mgechev.com/2016/08/14/ahead-of-time-compilation-angular-offline-precompilation/
只是猜测一下......但是当用AOT编译器编译时,这个代码是否可能实际上没有执行?
mainRoutes.push({
path: "second",
component: SecondComponent
})
它似乎不在任何Angular组件或服务中。
您是否可以更明确地了解您要使用此代码完成的任务?您是否尝试加载动态组件?
您可以使用以下代码:
export class AppModule {
constructor(router: Router) {
const config = router.config;
config.push({path: 'second', component: SecondComponent});
router.resetConfig(config);
}
}
请记住,您只需在entryComponents中添加动态组件。
@mcsekar也提出了这段代码
import { BrowserModule } from '@angular/platform-browser'
import { NgModule } from '@angular/core'
import { RouterModule, Routes, Router } from '@angular/router'
import { AppComponent } from './app.component'
import { FirstComponent } from './first.component'
import { SecondComponent } from './second.component'
let routes: Routes = [{
path: "first",
component: FirstComponent
}];
@NgModule({
declarations: [
AppComponent,
FirstComponent
],
imports: [
RouterModule.forRoot(routes),
BrowserModule
],
providers: [],
entryComponents:[SecondComponent],
bootstrap: [AppComponent]
})
export class AppModule {
constructor(router: Router) {
const config = router.config;
config.push({path: 'second', component: SecondComponent});
router.resetConfig(config);
}
}