Angular路由在创建后不在生产中推送到数组

问题描述 投票:10回答:2

我已经创建了一个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编译用于生产的问题。

angular angular2-routing development-environment production-environment
2个回答
4
投票

简短的回答是,当您为生产编译时,它使用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组件或服务中。

您是否可以更明确地了解您要使用此代码完成的任务?您是否尝试加载动态组件?


0
投票

您可以使用以下代码:

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);
  }

 }
© www.soinside.com 2019 - 2024. All rights reserved.