深层嵌套组件不显示

Deep nested components not displaying

我无法显示第三个嵌套组件。

预计:

Hello App Component

Hello Nest-A Component

Hello Nest-1 Component

Hello Test-Z Component

实际:

Hello App Component

Hello Nest-A Component

Hello Nest-1 Component

为什么我的 Test-Z 组件不显示?

TLDR; StackBlitz - Code Example

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { NestAModule } from './nest-a/nest-a.module';

const rootRoutes: Routes = [
  { path: '', redirectTo: 'nest-a', pathMatch: 'full' },
  { path: 'nest-a', redirectTo: 'nest-a', pathMatch: 'full' },
];

@NgModule({
  imports: [ 
    BrowserModule, 
    FormsModule,
    RouterModule.forRoot(rootRoutes),
    NestAModule,
  ],
  declarations: [ 
    AppComponent, 
  ],
  bootstrap: [ 
    AppComponent 
  ]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: '<h1>Hello App Component</h1><router-outlet></router-outlet>',
})
export class AppComponent {
}

nest-a/nest-a-routing-module.ts

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { NestAComponent } from './nest-a.component';
import { Nest1Component } from './nest-1/nest-1.component';

export const nestARoutes = [
  {
    title: 'Nest A',
    path: 'nest-a',
    component: NestAComponent,
    children: [
      { path: '', redirectTo: 'nest-1', pathMatch: 'full' },
      { path: 'nest-1', component: Nest1Component },
    ],
  },
];

@NgModule({
  imports: [
    RouterModule.forChild(nestARoutes),
  ],
  exports: [
    RouterModule
  ]
})
export class NestARoutingModule { }

nest-a/nest-a.component.ts

import { Component } from '@angular/core';

@Component({
    selector: 'my-nest-a',
    template: `<h1>Hello Nest-A Component</h1><router-outlet></router-outlet>`
})
export class NestAComponent {
}

nest-a/nest-a.module.ts

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { NestAComponent } from './nest-a.component';
import { NestARoutingModule, nestARoutes } from './nest-a-routing.module';
import { Nest1Module } from './nest-1/nest-1.module';


@NgModule({
  declarations: [
    NestAComponent,
  ],
  imports: [
    NestARoutingModule,
    Nest1Module,
    RouterModule.forChild(nestARoutes),
  ],
})
export class NestAModule { }

nest-a/nest-1/nest-1-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { Nest1Component } from './nest-1.component';
import { TestYComponent } from './test-y/test-y.component'
import { TestZComponent } from './test-z/test-z.component'

export const nest1Routes = [
  {
    title: 'Nest 1',
    path: 'nest-1',
    component: Nest1Component,
    children: [
      { path: '', redirectTo: 'test-z', pathMatch: 'full'},
      { path: 'test-y', component: TestYComponent},
      { path: 'test-z', component: TestZComponent},
    ]
  },
];

@NgModule({
  imports: [
    RouterModule.forChild(nest1Routes),
  ],
  exports: [
    RouterModule
  ]
})
export class Nest1RoutingModule { }

nest-a/nest-1/nest-1.component.ts

import { Component } from '@angular/core';

@Component({
    selector: 'my-nest-1',
    template: `<h1>Hello Nest-1 Component</h1><router-outlet></router-outlet>`
})

export class Nest1Component {
}

nest-a/nest-1/nest-1.module.ts

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { Nest1Component } from './nest-1.component';
import { Nest1RoutingModule, nest1Routes } from './nest-1-routing.module';
import { TestZModule } from './test-z/test-z.module'

@NgModule({
  declarations: [
    Nest1Component,
  ],
  imports: [
    Nest1RoutingModule,
    TestZModule,
    RouterModule.forChild(nest1Routes),
  ],
})
export class Nest1Module { }

nest-a/nest-1/nest-/nest-.component.ts

(有一个Y和Z,没有重要区别)

import { Component } from '@angular/core';

@Component({
    selector: 'my-test-*',
    template: `<h1>Hello Test-* Component</h1>`
})

export class Test*Component {
}

您的代码中有几处错误,对路由器解析造成了一些麻烦:

  • 你的路径分为不同的模块,但在路由定义中你告诉路由器直接加载一个组件而不是整个子模块(包含子模块路由定义)
  • 在您的子模块中,您需要将第一个路径设为空以加载模块主要组件(在 nest-1 模块中,您的空路径将加载 nest-1 组件。它不是具有加载子模块 entry 组件的工作)
  • 你的路由是在路由模块和主模块中设置的(例如:在 nest-a.module 和 nest-a.routing.module 中你有这一行 RouterModule.forChild(nestARoutes),).它们必须只在一个地方定义(路由模块,然后在主模块中导入)
  • 路由器负责加载子模块(使用路径定义中的loadChildren 属性)所以你不需要在父模块中导入子模块( es: nest-a.module 不需要导入 nest-1.module

下面您会发现您的示例已按上述说明进行了修改。主要的两件事是:

  • 在你的父模块路由定义中你需要使用loadChildren 属性来加载子模块(和他的路由定义)
  • 在子模块中,第一个路径为空并加载子模块 entry 组件(es:nest-1 模块将加载 nest-1 组件)

WORKING EXAMPLE

希望我说得够清楚了。

更新我的代码 Luca Regazzi 的回答后,我开始在生产中收到以下错误消息。

Error: Uncaught (in promise): Error: Runtime compiler is not loaded

Error: Runtime compiler is not loaded

AOT 似乎还有另一种方法来加载已记录的儿童 In this Bug Report on Angular/Angular-cli

而不是:

import { MyComponent } from './path/mycomponent.component';

...

loadChildren: () => MyComponent

应该是:

// no import

...

loadChildren: () => import('./path/mycomponent.component')
  .then(m => m.MyComponent)