@NgModule 的重要作用
在 Angular 中,NgModule 有以下几个重要的作用:
NgModule 最根本的意义是帮助开发者组织业务代码,开发者可以利用 NgModule 把关系比较紧密的组件组织到一起,这是首要的。
NgModule 用来控制组件、指令、管道等的可见性,处于同一个 NgModule 里面的组件默认互相可见,而对于外部的组件来说,只能看到 NgModule 导出( exports )的内容
这一特性非常类似 Java 里面 package 的概念。
也就是说,如果你定义的 NgModule 不 exports 任何内容,那么外部使用者即使 import 了你这个模块,也没法使用里面定义的任何内容。
@NgModule 例子
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { TestViewChildComponent } from './test-view-child/test-view-child.component';
import { ChildOneComponent } from './test-view-child/child-one/child-one.component';
@NgModule({
declarations: [
AppComponent,
TestViewChildComponent,
ChildOneComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
- declarations:用来放组件、指令、管道的声明。
- imports:用来导入外部模块。
- providers:需要使用的 Service 都放在这里。
- bootstrap:定义启动组件。你可能注意到了这个配置项是一个数组,也就是说可以指定多个组件作为启动点,但是这种用法是很罕见的。
@NgModule一些注意点:
- 每个应用至少有一个根模块,按照惯例,根模块的名字一般都叫
AppModule
,如果你没有非常特别的理由,就不要随意改这个名字了,这相当于一个国际惯例。
NgModule 和 ES6 Module
这两个是完全不同的两个概念。
- ES6 里面的模块是通过 export 和 import 来进行声明的,它们是语法层面的内容;而 NgModule 完全不是这个概念,从上面的作用列表你也能看出来。最重要的一点,目前,ES6 里面的 import 只能
静态引入模块
,并不能异步动态加载模块。 - NgModule 可以配合
Router 来进行异步模块加载
。 模块的定义方式会影响依赖注入机制:
对于直接 import 的同步模块
,无论你把 @Injectable 类型的组件定义在哪个模块里面,它都是全局可见的
。
比如:
在子模块 post.module.ts 的 providers 数组里面定义了一个 PostListService,你可能会觉得这个 PostListService 只有在 post.module.ts 里面可见。而事实并非如此, PostListService 是全局可见的,就相当于一个全局单例。
与此对应,如果你把 PostListService 定义到一个异步加载的模块里面,它就不是全局可见的了,因为对于异步加载进来的模块,Angular 会为它创建独立的 DI( Dependecy Injection,依赖注入)上下文。 但是在angular中异步模块加载一般是component 组件
所以,如果你想让 PostListService 全局可见,应该把它定义在根模块 app.module 里面。同时要特别注意,如果你希望 PostListService 是全局单例的,只能在 app.module 里面的 providers 数组里面定义一次,而不能在其它模块里面再次定义,否则就会出现多个不同的实例。
利用这个特性,我们通常把整个应用的service
都放在一个shareModule里面,其他模块需要使用这些服务的时候,只需要import shareModule就可以了,即使shareModule并没有exports 这些 service
,import shareModule就可以使用这些service
。
而shareModule里面如果有declaration 一个组件
,但是如果shareModule 没有exports 这个组件
,即使你import shareModule,也不能使用shareModule 的这个组件
。