Angular 模块
从 Angular 的基本构建块开始,本节课我们将了解 Angular 模块是什么,以及它们如何让 Angular 开发更加简便和模块化。
在开发环境准备就绪后,我们现在可以学习构成 Angular 应用程序的基本构建块,包括组件、模块、服务和管道等。
这一过程中的第一步是理解 Angular 模块的概念。
常见问题
以下是大多数初学者常问的一些问题:
Q. Angular 模块是一种容器吗?
Q. Angular 模块和 JavaScript 模块是一样的吗?
Q. Angular 模块是包含某些业务逻辑的代码块吗?
本节课将解答这些问题。
Angular 模块
Angular 模块是任何 Angular 应用程序中的关键组成部分。

从上图可以看出,当你在 Angular 中使用模块时,应用程序的结构会呈现出怎样的形态。
模块化使应用更加逻辑清晰、结构分明,所有功能都按模块划分定义。
你可以将模块看作一个被 @NgModule 装饰的类。这有助于组织应用内部的各种元素,并通过集成第三方库来实现交互。
同时,它还允许我们将子模块导入或导出给其他模块使用。
@NgModule 装饰器包含了该类的元数据,用于描述 Angular 模块的行为。NgModules 包含多个元素,这些将在本节后续内容中详细讨论。
JavaScript 模块与 Angular 模块的区别
为了更好地理解 Angular 模块,我们需要区分 JavaScript 模块和 Angular 模块的不同之处。
在 JavaScript 中,我们常常面临命名空间的问题;而 Angular 通过模块机制解决了这个问题,帮助实现代码的模块化。ES2015 模块支持导入和导出,而 Angular 模块则创建了由组件组成的容器。一个组件只能属于一个模块。
虽然 JavaScript 模块帮助我们组织代码,但 Angular 模块则用于构建整个 Angular 应用的结构。每个 Angular 应用至少包含一个模块,即根模块。
模块长什么样?
1import { BrowserModule } from '@angular/platform-browser'; 2import { NgModule } from '@angular/core'; 3import { FormsModule } from '@angular/forms'; 4import { AppRoutingModule } from './app-routing.module'; 5import { AppComponent } from './app.component'; 6import { AssessmentsModule } from './assessments/assessments.module'; 7import { CoreModule } from './core/core.module'; 8import { SharedModule } from './shared/shared.module'; 9import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 10 11@NgModule({ 12 declarations: [ 13 AppComponent, 14 ], 15 imports: [ 16 BrowserModule, 17 AppRoutingModule, 18 AssessmentsModule, 19 CoreModule, 20 SharedModule, 21 FormsModule, 22 BrowserAnimationsModule 23 ], 24 providers: [], 25 bootstrap: [AppComponent] 26}) 27export class AppModule { }
Angular 模块是一个使用 @NgModule 装饰的类,其中包含多个数组,如声明数组、导入数组等。
模块是如何工作的?
下面我们逐一分析这些数组的作用。
bootstrap数组
该数组包含在 Angular 应用启动时需要初始化并渲染的组件。必须至少在bootstrap数组中指定一个组件,但此数组只能在根应用模块中定义。
1bootstrap: [...]
declarations数组
该数组包含当前模块中定义的组件、管道和指令。
1declarations: [ 2 AppComponent, 3 ColorHighlightDirective, 4 OperatorPipe 5]
我们只能在 declarations 数组中定义组件、管道或指令,不能包含其他类或服务等。
imports 数组
该数组用于访问其他库或 Angular 模块中导出的模块。我们可以直接导入它们,并使用其提供的功能。常见的例子包括 FormsModule 和 RouterModule,以及其他如对话框模块或来自 Bootstrap 的模块。
重要提示:导入一个模块并不会自动获得其内部导入的模块的访问权限。
providers 数组
该数组曾用于在 NgModule 中声明服务。但现在不推荐这样做,而是建议在服务内部使用 providedIn 属性进行本地配置。这一点将在服务章节中详细讲解。
exports 数组
该数组允许我们将模块中定义的组件、管道和指令共享给其他模块。如果某个组件需要使用另一个模块中的组件,则必须将其导出,以便其他模块可以导入使用。我们不能导出服务,因为服务是通过依赖注入的方式提供给需要它的组件的。
功能模块与共享模块
Angular 模块有助于按功能对大型应用进行更好的组织,尤其是在应用规模较大、包含多个功能模块时。这时“功能模块”就显得尤为重要。
设想一个包含评估、结果和用户资料等功能的应用。为了保持关注点分离,最好将这些功能拆分为特定的模块。例如,一个模块专门管理所有评估功能,或某一类评估;另一个模块负责结果相关组件;其他模块则对应其他功能。
在上述代码示例中,AssessmentsModule 就是一个典型的功能模块。
而“共享模块”则是指存放所有可复用组件的容器。它将所有可复用的组件聚合在一起,无需逐个导出,只需导入这个共享模块即可使用所需的所有可复用组件。
使用 Angular CLI 创建模块
你可以使用 ng 命令行工具通过 CLI 创建模块。
1ng generate module <模块名>
或使用别名:
1ng g m <模块名>
这将生成一个带有 @NgModule 装饰器和必要数组的类。
如果你想指定模块创建的文件夹路径:
1ng g m <文件夹名>/<模块名>
或使用 --flat 标志避免创建新文件夹,直接在现有目录中生成。
若在创建模块的同时希望导入该模块,可以使用以下命令:
1ng g m <模块名> --flat -m main/main.module
其中 -m 表示指定要导入的模块,后面跟的是新模块应被导入的目标模块。