Reputation: 9139
My main AppModule
has recently grown significantly so I want to cut it into multiple smaller modules. As the first step, I took a number of login / registration components and placed them in LoginModule
. There is one problem, though. Components that I've placed in LoginModule
depends on another module that is declared and configured in the main AppModule
. This required module accepts a number of configuration parameters and of course, I'd like to have it configured in one single place.
As an example, let's take IonicModule
but this question is Angular2-generic.
My main AppModule
imports IonicModule
and LoginModule
as well as provides a number of parameters to the IonicModule
.
imports: [
IonicModule.forRoot(MyApp, {
mode: 'ios',
tabsPlacement: 'bottom'
}),
LoginModule
]
Because all components in LoginModule
depends on IonicModule
I need to import IonicModule
there as well. What should I do with configuration parameters, though? I'd like to avoid copy-pastying them from AppModule
.
Is imports: [IonicModule]
in this case enough? Or do I need to extract configuration parameters somewhere and inject them every time I refer IonicModule
?
All other modules that I will extract, will need to have IonicModule
imported as well.
@NgModule({
imports: [IonicModule],
declarations: [
(...)
],
entryComponents: [
(...)
],
providers: (...)
})
export class LoginModule {}
Upvotes: 2
Views: 691
Reputation: 3000
What you're looking for is to create a core module which is recommended by the official Angular Style Guide.
Here is how you can refactor your app to meet the style guide, keep all of your config in one place, and create a very organized and lean app:
To reduce root folder clutter create a Core Module that we import once when the app starts and never import anywhere else.
app/core
folderapp/
to app/core
(e.g. IonicModule)import {
ModuleWithProviders, NgModule,
Optional, SkipSelf } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicModule } from 'ionic-angular';
import { ExampleComponent } from './example.component';
import { ExampleService } from './example.service';
@NgModule({
imports: [
CommonModule,
IonicModule.forRoot(MyApp, {
mode: 'ios',
tabsPlacement: 'bottom'
})
],
declarations: [ ExampleComponent ],
exports: [ ExampleComponent ]
})
export class CoreModule {
}
forRoot()
method only needs to be imported once into the CoreModule
. After doing this, it will be available to every module in your app.CoreModule
(forRoot)Put this in the CoreModule
class:
static forRoot(): ModuleWithProviders {
return {
ngModule: CoreModule,
providers: [
ExampleService
]
};
}
This is the only place you should put app-wide singleton providers. Do not place them in a SharedModule.
CoreModule
into the AppModule
Add CoreModule.forRoot()
to your AppModule
imports like this:
imports: [
AppRoutingModule,
BrowserModule,
CoreModule.forRoot()
],
Call
forRoot
only in the root application module,AppModule
. Calling it in any other module, particularly in a lazy loaded module, is contrary to the intent and is likely to produce a runtime error.
CoreModule
(optional, but recommended)At this point everything should work, but it's a best practice to prevent reimporting the CoreModule
. This is especially helpful when working with others because another developer may not be fully aware of how a CoreModule
should be used.
Add this to your CoreModule
's class:
constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
throwIfAlreadyLoaded(parentModule, 'CoreModule');
}
Lazy-loaded routes
Consider creating lazy-loaded routes. This way the initial load of your app can be faster by only loading what is required by the current route.SharedModule
Consider creating a SharedModule
that does not include app-wide services. You can put components in here that will be required by certain routes, but not all routes.Why?
The purpose of this is that if you load a lazy-loaded route that does not require a component of the shared service it will not download if that is the first route requested when the app first loads. This will speed up your initial app loading time. Of course, if a route is called that needs it, then the component will be available as expected.Upvotes: 1
Reputation: 29625
You could take a look at shared modules section here
Theoretically,you could set the common dependancy modules in one module , export from there and import that. That way you could still set the parameters in one place. However , I havent tried doing this with a module that takes the app component in forRoot.
@NgModule({ imports: [IonicModule.forRoot(),//other deps with parameters],
declarations: [ (...) ], entryComponents: [ (...) ],
providers: (...) ,
exports:[//export deps]})
export class commonModule {}
Hope it helps
Upvotes: 0