I'm working on a MEAN project via Angular 2, and am setting up the routing for my various pages. I've seen a lot of examples that use ModuleWithProviders to do routing, rather than the angular.io example with NgModule (https://angular.io/guide/router)
Which is the standard way of doing things? If either is acceptable, is there a performance difference between the two?
ModuleWithProviders example:
import { ModuleWithProviders } from '@angular/core';
import {Routes, RouterModule} from '@angular/router';
import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component';
import { ServicesComponent } from './services/services.component';
export const router: Routes = [
{ path: '', redirectTo: 'about', pathMatch: 'full'},
{ path: 'about', component: AboutComponent },
{ path: 'services', component: ServicesComponent }
];
export const routes: ModuleWithProviders = RouterModule.forRoot(router);
NgModule Example:
import { NgModule } from '@angular/core';
import {Routes, RouterModule} from '@angular/router';
import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component';
import { ServicesComponent } from './services/services.component';
export const router: Routes = [
{ path: '', redirectTo: 'about', pathMatch: 'full'},
{ path: 'about', component: AboutComponent },
{ path: 'services', component: ServicesComponent }
];
@NgModule({
imports: [
RouterModule.forRoot( router )
],
exports: [
RouterModule
]
})
export class AppRoutingModule {}
ModuleWithProviders is the interface that is supposed to be returned by forRoot method. ModuleWithProviders object is plain object that has ngModule property that contains actual module class augmented with additional providers in providers property. Since ModuleWithProviders is an interface, its usage is optional.
forRoot creates a module that contains all the directives, the given routes, and the router service itself. forChild creates a module that contains all the directives and the given routes, but does not include the router service. It registers the routers and uses the router service created at the root level.
The forRoot() method creates an NgModule that contains all the directives, the given routes, and the Router service itself. The forChild() method creates an NgModule that contains all the directives and the given routes, but does not include the Router service.
There are two types of modules, root modules and feature modules. In the same way that in a module we have one root component and many possible secondary components, in an application we only have one root module and zero or many feature modules.
NgModule and ModuleWithProviders are different things.
NgModule
is a decorator for module classes.
ModuleWithProviders
is the interface that is supposed to be returned by forRoot
method. ModuleWithProviders
object is plain object that has ngModule
property that contains actual module class augmented with additional providers in providers
property.
Since ModuleWithProviders
is an interface, its usage is optional.
estus is absolutely right about the difference between the two (@NgModule
is a decorator while ModuleWithProvider
is an interface) but practically speaking, the answer to your question that which approach is better would be:
The second approach is more clear, more common and the best practice because it defines the routes in a separate module which it will be later imported to AppModule
:
export const routes: Routes = [
{ path: '', redirectTo: 'about', pathMatch: 'full'},
{ path: 'about', component: AboutComponent },
{ path: 'services', component: ServicesComponent }
];
const config: ExtraOptions = {
useHash: true
};
@NgModule({
imports: [RouterModule.forRoot(routes, config)],
exports: [RouterModule]
})
export class AppRoutingModule {}
Importing to AppModule
@NgModule({
declarations: [AppComponent],
imports: [AppRoutingModule],
bootstrap: [AppComponent],
})
export class AppModule {}
Although, what mentioned above hopefully answered your question, I like to also point out the difference between importing RouterModule
in AppModule
and sub-modules:
For the AppModule
:
RouterModule.forRoot(routes)
For sub-modules:
RouterModule.forChild(routes)
Why? RouterModule
gives you
The first time in app module, forRoot
will give the router components and provide the router services. But the next times in sub-modules, forChild
will only give the router components (and not providing again the services, which are already available via the app module import).
Want to read more? I found this article amazing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With