Angular 模块漫谈

Photo by Vanessa Lang on Unsplash

模块是 一个 Angular 应用组织的重要一环,通过模块之间的导入导出,我们可

以把复杂的功能分解到各个模块中,增强了代码的复用性可维护性。但是这也

引入了一定的学习复杂度。本教程从 Angular 模块入手,将 Angular 应用组

织方式和模块中资源的可见性做了详细的解释。读完本文,相信会对 Angular

有更新的认识。

约定

模块自身定义的组件、管道、指令以及服务统称为模块本身的——资源。

应用的组成

模块是如何组织本模块与外部模块资源的?我们可以仔细观察下图。

可以清楚的看到,一个 Angular 应用由多个模块构成。通过 imports 关键字,

每个模块可以复用其他模块导出的资源。imports 就像针线一般将各个模块串

联起来,构成一个复杂的 Angular 应用。

本模块的资源

declarations 声明的资源其作用域被限制在本模块中。必须资源的拥有者模块

只有使用 exports 导出了这些资源,它们才能被其他模块所用。

服务是特殊的资源

服务是一种非常特殊的资源,它们在模块中通过 providers 关键词指定。一旦

模块中创建了服务,并且此模块被其他模块导入到了应用中,那么应用在启动

时就会在全局生命周期内生成一个单一的服务实例。应用下的任何组件都能使

用这个服务实例。

外部模块的使用

当使用一个外部模块时,你可以记住这三条原则:

一、如果外部模块不含服务,仅仅包含组件类 ,那么你只要在特性模块中导入

这个模块即可!

二、如果该外部模块只包含服务。比如 HttpClientModule 这类的外部模块,

我们只需要在 AppModule 中导入一次即可。

三、如果外部模块既包含服务又包含其他资源,那么就只须在 AppModule 中

导入此模块的服务,而在特性模块中导入外部模块的其他资源。一般来说,这

种含服务又包含组件类的第三方模块会提供静态方法 forRoot 和 forChild 方

法。在 AppModule 中我们使用 forRoot 注册全局的服务示例,而在特性模块

中,使用 forChild 导入服务以外的其他资源。

常见的例子——RouterModule

就常见的 RouterModule 来说。我们会使用 RouterModule 提供的指令

<router-outlet> 来动态生路由页面 ,也要使用服务 ActivatedRoute 来获取路

由参数或者 Resovler 数据。我们只要在 AppModule 中使用 forRoot 方法来

提供包含服务在内的所有资源。

而在其他特性模块中就只要使用 forChild 导入组件类即可(不需要服务)。

参考资料

Understanding Angular modules (NgModule) and their scopes

发表评论

电子邮件地址不会被公开。 必填项已用*标注