Angular 2 No provider for RouterOutletMap when laz

2019-03-06 02:33发布

问题:

I'm using the latest Angular CLI build (16) and I'm trying to lazy load routes but it fails for some reason, I can't find any new questions or solutions for this.

Folder structure:

core.component.html:

<router-outlet></router-outlet>

core.component.ts:

import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {RouterModule} from '@angular/router';

// Modules
import {AdminAreaModule} from './+admin-area';

// Services
import {GlobalsService, RegexService, UtilsService} from './shared';

// Main app component
import {CoreComponent} from './core.component';

@NgModule({
  imports: [
    BrowserModule,

    // Feature modules
    AdminAreaModule
  ],
  exports: [
    BrowserModule
  ],
  declarations: [
    CoreComponent
  ],
  providers: [
    GlobalsService,
    RegexService,
    UtilsService
  ],
  bootstrap: [CoreComponent]
})
export class CoreModule {}

admin-area-router.module.ts:

import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';

// Global modules
import {ComponentsModule, SharedModule} from '../../shared';

// Lazy loaded modules
import {AdminAreaModule} from '../admin-area.module';

@NgModule({
  imports: [
    RouterModule.forChild([
      {
        path: 'admin',
        loadChildren: 'app/+admin-area/admin-area.module#AdminAreaModule'
      }
    ])
  ],
  exports: [
    RouterModule
  ]
})
export class AdminAreaRouterModule {}

admin-area.module.ts:

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

import {AdminAreaRouterModule} from './router';

import {ComponentsModule, SharedModule} from '../shared';

@NgModule({
  imports: [
    ComponentsModule,
    SharedModule,

    // Feature modules
    AdminAreaRouterModule
  ],
  exports: [
    ComponentsModule,
    SharedModule,
    AdminAreaRouterModule
  ]
})

export class AdminAreaModule {}

This throws an error:

Error in ./CoreComponent class CoreComponent - inline template:0:0 caused by: No provider for RouterOutletMap!

Why am I getting this error when I clearly have a router-outlet in my core.component.ts file?

回答1:

You don't have routing defined in the core module, but you do have a router-outlet.

Hence the error no provider (aka no routing is provided) for routeroutletmap (router-outlet)

Even if you have routing in your submodule (in this case, the admin module), you also need to add routing to the core module. For example, { path: '', redirectTo: '/admin', pathMatch: 'full' }



回答2:

This is not how routing works. The router with loadChildren going to admin should not be inside admin. It should be in a higher level, for example, in core.

As a side effect of that, when you import the router in core, you'll get all the directives from that module, including router-outlet.

See this repository here to see how routing lazy loading works:
https://github.com/meligy/routing-angular-cli

In this repo, app is similar to your core, and lazy is similar to your admin.

AppRoutingModule is in the NgModule imports of AppModule. AppRoutingModule has a route that looks like this:

  {
    path: 'lazy',
    loadChildren: './lazy/lazy.module#LazyModule'
  }

(yes, you can define paths relatively, as of beta-17)

Then, inside the /lazy folder, LazyRoutingModule is in the NgModule imports of LazyModule.

LazyRoutingModule has all the routes inside /lazy. It doesn't know it's going to be /lazy. Only AppRoutingModule knows that.

LazyRoutingModule only knows that whatever path the AppRoutingModule chooses for it, LazyRoutingModule will control the child routes it defines under that.

That's why AppRoutingModule is defined like this:

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: []
})
export class AppRoutingModule { }

While LazyRoutingModule is defined as:

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
  providers: []
})
export class LazyRoutingModule { }

Note the forRoot() vs the forChild().

With that all translated to your project words (again, app becomes core, and lazy becomes admin, if I understand your project structure right), you should be able to lazy load the admin folder.

Let me know how it goes.