30

As far as Angular 2 routing goes, I've mostly been able to find examples of the scenario where there's exactly one routing file for the whole application.

I'd like to see an example of using not just one routing file, but a main routing file and then at least one feature module routing file.

Edit: I realize that a somewhat similar question has already been asked and answered. There are two reasons why I don't find that one particularly helpful:

1) The question is very specific to that user's situation and therefore there's a lot of "noise". All I'm asking for is one single isolated example of feature module routing.

2) The answers for that question don't seem to address how to create a routing file for a feature module and then tie it back into the app's main routing. Maybe it's there and I'm just missing it but I don't see it there.

6
  • angular.io/docs/ts/latest/guide/router.html Commented Nov 27, 2016 at 23:01
  • 1
    I've seen the docs. I didn't find what I saw there very satisfying for this purpose. Commented Nov 27, 2016 at 23:47
  • 2
    Not even the part they mentioned how we can have a separate routing file for each module? I think you can search for 'We recommend giving each feature area its own route configuration file.' in that doc page and continue from that part. Commented Nov 28, 2016 at 0:09
  • Possible duplicate of Angular2 RC6 - Nested modules with routing Commented Nov 28, 2016 at 6:18
  • See sample of BLog app with Angular 2 and Strongloop(loopback) as rest service github.com/tabvn/angular-blog Commented Nov 28, 2016 at 7:03

2 Answers 2

52

Let's see if this example covers what you are looking for.

These are the modules being used:

  • AppModule (root module)
  • UsersModule (feature module)

Snippets below are simplified.

app.module.ts

import { UsersModule } from './users.module';
import { AppRouting } from './app.routing';

@NgModule({
  imports: [
    BrowserModule,
    UsersModule,
    AppRouting,
  ],
  declarations: [...],
  providers: [...],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

app.routing.ts

const appRoutes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'home', component: Home },
  { path: '**', component: NotFound }, //always last
];

export const AppRouting = RouterModule.forRoot(appRoutes, { 
  useHash: true
});

users.module.ts

import { NgModule } from '@angular/core';
import { UsersRouting } from './users.routing';

@NgModule({
  imports: [
    CommonModule, // ngFor, ngIf directives
    UsersRouting,
  ],
  declarations: [...],
  providers: [...]
})
export class UsersModule { }

users.routing

const usersRoutes: Routes = [
  { path: 'users',
    children: [
      { path: '', component: Users },
      { path: ':id', component: User }
    ]
  }
];

export const UsersRouting = RouterModule.forChild(usersRoutes);

Plunker: http://plnkr.co/edit/09Alm0o4fV3bqBPUIFkz?p=preview

Sample code includes also AboutModule (lazy loaded module, includes resolve example) but doesn't include a Shared Module example.

You can find more details at these slides: https://slides.com/gerardsans/ngpoland-amazing-ng2-router

Sign up to request clarification or add additional context in comments.

4 Comments

thanks for the concise answer, the Angular docs make the Routing a full @NgModule, didn't realize I could just export it as a const.. handy!
I'm not that deep in matter, so is there a benefit or a specific reason why you exported them just as const instead of @NgModule class as it is in the angular/cli generated app-routing.module.ts?
What's missing here is how you get from AppMoudle to UserModule. There is no path in root routing that points to user
@CodyBugstein -- I thought the same thing too initially, but our mental model of it is a bit incorrect. The users.routing file is calling RouterModule.forChild(usersRoutes). This basically grafts/inserts the entire userRoutes object into the routes in AppModule, so that the /users path is a root level child...
3

Here is an example of how I handle my routing with child routes. I think this will help you and teach you to use child routes to provide Guard for some of your components. This will secure some views if the user is lacking authentication. I separate mine in public and secure routing everything through the layout then loading the routes for which ever layout is chosen.

Make sure to export the child routes and that the correct routes are called in the layout route. Also make sure you use redirectTo in each child routes file.

We are defining our layouts public or secure. Then providing the routes file in each of those directories to take over once the create route is picked.

app.routing.ts

const APP_ROUTES: Routes = [
    { path: '', redirectTo: '/home', pathMatch: 'full', },
    { path: '', component: PublicComponent, data: { title: 'Public Views' }, children: PUBLIC_ROUTES },
    { path: '', component: SecureComponent, canActivate: [Guard], data: { title: 'Secure Views' }, children: SECURE_ROUTES }
];

Then I have a layouts folder

layouts

layouts/public/public.components.ts
layouts/public/public.components.html
layouts/secure/secure.components.ts
layouts/secure/secure.components.html

secure.component.ts which is the layout looks like this,

import { Component, OnInit }        from '@angular/core';
import { Router }                   from '@angular/router';
import { Auth }                     from './../services/auth.service';

@Component({
    providers: [ Auth ],
    selector: 'app-dashboard',
    templateUrl: './secure.component.html'
})
export class SecureComponent implements OnInit {

    constructor( private router: Router, private auth: Auth ) { }

    ngOnInit(): void { }
}

Then in your secure directory you can create a component and select the template you will use for it,

@Component({
    providers: [ Auth ],
    templateUrl: './profile.component.html'
})
export class ProfileComponent implements OnInit {

    constructor( private router: Router, private auth: Auth, private http: Http  ) { }

    ngOnInit() { }
}

Now make sure to create your child routes in the secure and public directory. Once the route is hit the child route will load the correct class and template file will be rendered.

Remember they will be children of your layouts. So you can put a navigation bar and footer in secure.component.html and it will show up in all of your secure components. Because we are using selectors to load the content. All of your components secure and public will be loaded into the selctory inside the layouts html file.

child routes /public/piublic.routes.ts

export const PUBLIC_ROUTES: Routes = [
    { path: '', redirectTo: 'home', pathMatch: 'full' },
    { path: 'p404', component: p404Component },
    { path: 'e500', component: e500Component },
    { path: 'login', component: LoginComponent },
    { path: 'register', component: RegisterComponent },
    { path: 'home', component: HomeComponent }
];

/secure/secure.routes.ts

export const SECURE_ROUTES: Routes = [
    { path: '', redirectTo: 'overview', pathMatch: 'full' },
    { path: 'items', component: ItemsComponent },
    { path: 'overview', component: OverviewComponent },
    { path: 'profile', component: ProfileComponent },
    { path: 'reports', component: ReportsComponent }
];

Summary

We have setup an initial rout file in the root directory of our Angular2 app. This route file directs traffic to one of two layouts depending on if the user is authenticated or not. If they have the authentication for whichever route public layout or secure layout iss served. Then each of those layouts have a bunch of child routes and components which are served to the respective layout.

So to clear the file structure up,

root = /

You main app routes which control which layout is viewed.

/app.routing.ts

Layouts which hold the layouts secure or public.

Public

`/layouts/public.components.ts
/layouts/public.components.html
/layouts/public.routing.ts`

Secure

`/layouts/secure.components.ts
/layouts/secure.components.html
/layouts/secure.routing.ts`

public directory which holds anything that is open to view without auth.

/public/home-component.ts
/public/home-component.html

Secure directory which holds the auth needed routes and components.

/public/profile-component.ts
/public/profile-component.html

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.