简体   繁体   中英

How to add ngModule routes as child routes of another ngModule in Angular2?

I am following this tutorial to have an architecture of my application.

To give more information lets consider A as appModule, and B is another main module. Now I want to load other modules ( NgModule which has many other routes) inside B's <router-outlet> .

What is a better approach to do this?

这就是我想要实现的目标

This is what I have done so far

-mainBoard (Folder next to app.Module)
    --mainBoard Routes
    --mainBoard Component
    --mainHeader Component
    --mainFooter Component
    --mainSidenav Component

    -Users  (Folder inside mainBoard)
    --User Module
    --User Routes
    --UserList Component
    --UserDetail Component
    --UserSetting Component

    -Departments (Folder inside mainBoard)
    --Department Module
    --Department Routes
    --DepartmentList Component
    --DepartmentDetail Component

-Auth (Folder next to mainBoard folder)
    --Auth Module
    --Auth Component
    --Auth Routes
    -Sign-in (Folder)
    --Sign-in Component
    -Sign-up (Folder)
    --Sign-up Component

-App Module

I have 2 main modules, mainBoard and Auth. MainBoard has a header, sidenav,footer and in the center I want to load Users and Department using <router-outlet> .

I want to load localhost/app/users to load Userslist and localhost/app/department to load department list.

My main-board.module and users.module look like this

// main-board.module.ts
import {MainBoardRouting} from './main-board.routes';

import {UsersModule} from './users/users.module';
import {DepartmentsModule} from './departments/departments.module';

@NgModule({
    imports :[
        MainBoardRouting,
        UsersModule,
        DepartmentsModule
    ],
    declarations : [
        MainBoardComponent,
        MainHeaderComponent,
        MainFooterComponent,
        MainSidenavComponent
    ],
    providers: []
})
export class MainBoardModule{}

// Users.module.ts

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

import {usersRouting} from './users.routes';
import {UserListComponent} from './user-list';
import {UserDetailComponent} from './user-detail';

@NgModule({
    imports :[
        usersRouting
    ],
    declarations : [
        UserListComponent,
        UserDetailComponent
    ],
    providers: []
})
export class UsersModule{}

// main-board.routes

import { RouterModule,Routes } from '@angular/router';

import {  MainBoardComponent  } from './main-board.component';

const MainBoardRoutes: Routes = [{
    path: 'app',
    component: MainBoardComponent
}];
export const MainBoardRouting = RouterModule.forChild(MainBoardRoutes);

// users route

import { Routes, RouterModule } from '@angular/router';

import { UserListComponent }    from './user-list';
import { UserDetailComponent }  from './user-detail';

export const usersRoutes: Routes = [
  {path: '', redirectTo: 'app/users', pathMatch:'full'},
  { path: 'users',  component: UserListComponent },
  { path: 'user/:id', component: UserDetailComponent }
];

export const usersRouting = RouterModule.forChild(usersRoutes);

Is my approach right to have child NgModule with their own routings or do I have to change them to simple component and have all the routes in main-board Module routes?

Your methodology is correct. In this approach one needs to import only childmodule into parentmodule , that's it. Childmodule will take care of it's own routing. Similarly if you have nested modules, only modules need to be imported in parent routes rather than declaring lot of routes in one place.

Your approach is right. You want to split the routes to their own sub-modules. Technically you can move the routes to any module as they are merged but it will probably be a bad idea in the long term.

Plunker with resulting routes https://plnkr.co/edit/Y9ReEwnBZNId48xX1CDR?p=preview

@Component({
  selector: 'users',
  template: `
    <div>
      <h2>Users</h2>
      <ul><li *ngFor="let user of users">{{user}}</li></ul>
    </div>
  `,
})
export class Users {
  users = ["John", "Joe"];
}

const usersRoutes = [
  {path: 'users', component: Users}
];
const UsersRoutes = RouterModule.forChild(usersRoutes);


@NgModule({
  imports: [ CommonModule, UsersRoutes ],
  declarations: [ Users ],
  exports: [ Users ]
})
export class UsersModule {}

As said before from others, but I would like to be a little bit clear. Using sub-Module to divide application features is very good, as the application grows they permit to keep a simple code structure.

The best way to manage this process is to have a folders structure like this:

src
   - featureA
     - featureA.routes.ts
     - fefatureA.module.ts
     - component1
       - component1.ts
       - [...]
     - component2
       - component2.ts
       - [...]
     - [...]

   - featureB
     - featureB.routes.ts
     - fefatureB.module.ts
     - component1
       - component1.ts
       - [...]
     - component2
       - component2.ts
       - [...]
     - [...]

   - [...]

   - app-routing.module.ts
   - app.module.ts

In every feature's module you declare the routes for this particoular module: file feature.routes.ts:

const routerConfig: Routes = [
    {
        path: '',
        component: Component1
    },
    {
        path: 'other',
        component: Component2
    }
]

and they you import this routes in your feature's module file feature.module.ts:

    import { routerConfig } from "./feature.routes";
        @NgModule({
          imports: [ 
            RouterModule.forChild(routerConfig),
          ],
        })
export class FeatureModule{}

The last thing to do is to import all the stuff in your routing module, lazy loading is perfect for the performace of a tipical application.

file app-routing.module.ts:

import { FeatureAModule } from './featureA/featureA.module';
import { FeatureBModule } from './featureB/featureB.module';
    @NgModule({
      imports: [
        RouterModule.forRoot([
          { path: '', loadChildren: ()=> require("./featureA/featureA.module")["FeatureAModule"]},
{ path: 'feature-b', loadChildren: ()=> require("./featureB/featureB.module")["FeatureBModule"]},
        ],  
        { preloadingStrategy: PreloadAllModules}) //Define the loading strategy
      ],
    })
    export class AppRoutingModule {}

And finnaly importing the routing module into your app module file app.module.ts:

import { AppRoutingModule } from './app-routing.module';

@NgModule({
  imports: [
    AppRoutingModule,
  ],
})
export class AppModule {}

您需要在路由定义中使用loadChildren属性,而不是路由器中的子节点,然后指向子模块(作为由“#”分隔的字符串,或作为返回模块的函数)

your approach is right you should divide your routing specific to the module like user module related routing goes in user module it will be very help full as the size of application grows now i think you should try these modification .

//main-board routes file

  import { RouterModule,Routes } from '@angular/router';

 import {  MainBoardComponent  } from './main-board.component';

  const MainBoardRoutes: Routes = [{
       path: 'app',
       component: MainBoardComponent
  }];
 export const MainBoardRouting = 
 RouterModule.forRoot(MainBoardRoutes); // use for root instead of for child 

What you need is loadChildren

child.module.ts

const childRoutes: Routes = [
    {
        path: '',
        component: ChildComponentA
    },
    {
        path: 'other',
        component: ChildComponentB
    }
]

@NgModule({
    imports: [
        RouterModule.forChild(childRoutes)
    ]
})
class MyChildModule {}

app.module.ts

const appRoutes: Routes = [
    {
        path: 'children',
        // If using a function that returns the Module,
        // it will be "eager-loaded"
        loadChildren: () => MyChildModule
        // When using a string, it will be lazy-loaded
        // loadChildren: './path/to/child.module#MyChildModule'
    }
]

@NgModule({
    imports: [
        RouterModule.forRoot(appRoutes)
    ]
})
class AppModule {
}

hi below i have given a sample routing module for app.module and feature module.

app-routing module routing file contains the primary routes and feature module routing file contains the rooting for child roots. hope this helps the resulting roure is /feature/books

app-routing.module.ts //import this in app.module.ts

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

export const routes: Routes = [
  { path: 'feature', loadChildren: 'app/feature/feature.module#FeatureModule'},
  { path: '', redirectTo: 'feature', pathMatch: 'full' },
];

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

export class AppRoutingModule {
}

feature-routing.module.ts //import this in feature.module.ts

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

// ---- components imported----
import { BooksComponent } from './books/books.component';
import { FeatureComponent } from './feature.component';

const featureRoutes: Routes = [

  {
    path: '',
    component: FeatureComponent,
    children: [
      {path: '', redirectTo: 'books', pathMatch: 'full'},
      {path: 'books', component: BooksComponent},
      {path: '**', redirectTo: 'books', pathMatch: 'full'},
    ]
  }
];

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

I have done this in my recent project. Here is the sample

app.routing.ts

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

@NgModule({
imports: [
    RouterModule.forRoot([
        { path: '', loadChildren: '../home/home.module#HomeModule' },
        { path: 'settings', loadChildren: '../settings/settings.module#SettingsModule' },
        { path: 'home', redirectTo: '', pathMatch: 'full' }
    ])
],
exports: [
    RouterModule
]
})
export class AppRoutingModule {  
}

home.module.ts

//all necessary imports

@NgModule({
imports: [
    CommonModule,
    TranslateModule,
    FormsModule,
    RouterModule.forChild([
        {
            path: '', component: HomeComponent, canActivate: [SecureGuard]
        }
    ]),
    ViewCountPipeModule
],
declarations: [
    HomeComponent
],
providers: [
    SecureGuard,
    CommonService
]
})
export class HomeModule {
}

settings.module.ts

//all the necessary imports

@NgModule({
imports: [
    CommonModule,
    TranslateModule,
    FormsModule,
    RouterModule.forChild([
        {
            path: '', component: RouteHolderComponent,
            children: [
                { path: '', redirectTo: 'settings', pathMatch: 'full' },
                { path: 'settings', component: SettingsComponent },
                { path: 'profile', loadChildren: '../profile-settings/profile-settings.module#ProfileSettingsModule' },
                { path: 'account', loadChildren: '../account-settings/account-settings.module#AccountSettingsModule' }
            ], canActivate: [SecureGuard]
        }
    ]),
    RouteHolderModule
],
declarations: [
    SettingsComponent
],
providers: [
    SecureGuard, SettingsService
]
})
export class SettingsModule {
}

RouteHolderModule exports RouteHolderComponent which just has a <router-outlet></router-outlet> tag in it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM