共享模块
在多个特性模块中,可能存在公共的组件、指令和管道。我们可以添加SharedModule来存放这些公共组件、指令和管道,并且共享给那些需要它们的模块。
如,项目中公共的有AwesomePipe管道、HighlightDirective指令、CommonModule和FormsModule模块。可以定义SharedModule如下:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { AwesomePipe } from './awesome.pipe';
import { HighlightDirective } from './highlight.directive';
@NgModule({
imports: [ CommonModule ],
declarations: [ AwesomePipe, HighlightDirective ],
exports: [ AwesomePipe, HighlightDirective,
CommonModule, FormsModule ]
})
export class SharedModule { }
值得注意的有:
- 它导入了CommonModule,这是因为它的组件需要这些公共指令。
- 正如我们所期待的,它声明并导出了工具性的管道、指令和组件类。
- 它重新导出了CommonModule和FormsModule
重新导出其它模块
当回顾应用程序时,我们注意到很多需要SharedModule的组件也同时用到了来自CommonModule的NgIf和NgFor指令,并且还通过来自FormsModule的[(ngModel)]指令绑定到了组件的属性。那些声明这些组件的模块将不得不同时导入CommonModule、FormsModule和SharedModule。
通过让SharedModule重新导出CommonModule和FormsModule模块,我们可以消除这种重复。于是导入SharedModule的模块也同时免费获得了CommonModule和FormsModule。
如,导入SharedModule的AppModule根模块,在该根模块中声明的组件,如果使用到NgIf或NgFor指令就不需要在AppModule中再导入CommonModule模块,同理,如果在该根模块中声明的组件,如果使用到NgModel指令同样也不要在AppModule中导入FormsModule模块了。
实际上,SharedModule本身所声明的组件没绑定过[(ngModel)],那么,严格来说SharedModule并不需要导入FormsModule。
这时SharedModule仍然可以导出FormsModule,而不需要先把它列在imports中。
注:不要在共享模块中把应用级单例添加到providers中。 否则如果一个惰性加载模块导入了此共享模块,就会导致它自己也生成一份此服务的实例。
对于如只在AppComponent中使用一次的组件,我们没必要共享它。如:TitleComponent只被AppComponent用一次,我们就没必要共享它,即不要在SharedModule中导出这样的组件。
全应用级的单例服务,不应在共享模块的providers中。如:UserService是全应用级单例。 我们不希望每个模块都各自有它的实例。