1. @NgModule:
接收一个元数据对象,该对象告诉 Angular 如何编译和运行模块代码。 它标记出该模块拥有的组件、指令和管道, 并把它们的一部 分公开出去,以便外部组件使用它们。 它可以向应用的依赖注入器中添加服务提供商
-
声明哪些组件、指令、管道属于该模块。
-
公开某些类,以便其它的组件模板可以使用它们。
-
导入其它模块,从其它模块中获得本模块所需的组件、指令和管道。
-
在应用程序级提供服务,以便应用中的任何组件都能使用它。
2. 参数介绍:
exports:
可供导入了自己的模块使用的可声明对象(组件、指令、管道类)的列表。
这些导出的可声明对象就是模块的公开API。如果其它模块导入了当前模块,并且 当前模块已导出, 那么其它模块中的组件就可以引用来自当前模块的组件
一个模块可以把另一个模块加入自己的exports列表中,这时,另一个模块的所有公开组件、指令和管道都会被导出。
重新导出可以让模块的传递性更加明确。 如果模块A重新导出了CommonModule,然后模块B导入了模块A,那么模块B中的组件就能使用NgIf了,虽然模块B本身并没有导入过CommonModule。
declarations:
可声明类的列表,也就是属于当前模块的组件、指令和管道类。
这些声明的类对组件内部可见,但是对其它模块不可见,除非这些类从当前模块中导出过,并且其它模块导入了当前模块。
组件、指令和管道只能属于一个模块。如果尝试把同一个类声明在多个模块中,编译器就会报错。不要重新声明从其它模块中导入的类。
providers:
依赖注入提供商的列表。
bootstrap:
能被引导的组件列表。通常,在这个列表中只有一个组件,也就是应用的根组件。
entryComponents:
那些没有在任何可访问的组件的模板中引用过的组件列表。(一般不会用)
imports:
支撑模块的列表
在两种情况下组件模板可以引用其它组件、指令或管道:
或者所引用的类是声明在当前模块中的,
或者那个类已经从其它模块中导入进来了。
静态方法forRoot是一个约定,它可以让开发人员更轻松的配置模块的提供商
根模块和特性模块还共享着相同的执行环境。 它们共享着同一个依赖注入器,这意味着某个模块中定义的服务在所有模块中也都能用。
3. SharedModule 共享模块
为那些可能会在应用中到处使用的组件、指令和管道创建SharedModule。 这种模块应该只包含declarations,并且应该导出几乎所有declarations里面的声明。
SharedModule可以重新导出其它小部件模块,比如CommonModule、FormsModule和提供你广泛使用的UI控件的那些模块。
SharedModule不应该带有providers
在任何特性模块中(无论是你在应用启动时主动加载的模块还是之后惰性加载的模块),你都可以随意导入这个SharedModule。
4. CoreModule 核心模块
为你要在应用启动时加载的那些服务创建一个带providers的CoreModule。
只能在根模块AppModule中导入CoreModule。 永远不要在除根模块AppModule之外的任何模块中导入CoreModule。
考虑把CoreModule做成一个没有declarations的纯服务模块。
5. 特性模块
围绕特定的业务领域、工作流和工具集来为应用创建特性模块。特性模块一般可分成下面这几种:
领域特性模块。
带路由的特性模块
路由模块
服务特性模块
窗口部件特性模块
特性模块 | 指导原则 |
---|---|
领域 | 领域特性模块专注于一个特定的应用领域来提供用户体验,比如编辑消费者信息或下订单。 它们通常有一个顶级组件,并作为该特性的根组件。 内部则是它的一些子组件。 领域特性模块几乎总是由 领域特性模块很少会有 不要在领域特性模块中提供全应用级的单例服务。 领域特性模块的典型用法是只被更大的特性模块导入一次。 对于缺少路由的小型应用,它们可能只会被根模块 |
路由特性模块 | 路由特性模块属于领域特性模块的一种,它的顶层组件是路由器导航时的路由目标。 根据这个定义,所有惰性加载的模块都是路由特性模块。 这里的 路由特性模块不应该导出任何东西,这是因为它们中的任何组件都不可能出现在外部组件的模板中。 惰性加载的路由特性模块也不应该被任何模块导出。 那么做会触发一次主动加载,破坏了我们惰性加载的目的。 而主动加载的路由特性模块必须被其它模块导入,以便编译器了解它有哪些组件。 路由特性模块很少会有 不要在路由特性模块及其导入的模块中提供全应用级的单例服务。 |
路由模块 | 路由模块为其它模块提供路由配置。 路由模块将路由配置从它的关联模块分离开来。 路由模块通常会做这些: 定义路由。 添加路由配置到模块的 重新导出 添加守卫和解析器服务提供商到模块的 路由模块的名字应该和它的关联模块平行,比如使用“Routing”前缀, 如果关联模块是根 路由模块顺便重新导出 路由模块不应该有自己的 路由模块应该只被它的关联模块导入。 |
服务 | 服务模块用于提供工具类服务,比如数据访问和消息等。 理想情况下,它们应该完全由 服务模块应该只被根模块 不要在任何特性模块中导入它们。 如果你要违背这条指导原则,请务必想清楚你在做什么,并要有充分的理由。 |
窗口部件 | 窗口部件模块导出能用供外部模块使用的组件、指令和管道。 部件模块应该只有 窗口部件模块很少会有 如果任何模块的组件模板中需要用到这些窗口部件,就请导入相应的窗口部件模块。 |
特性模块 | 声明`declarations` | 提供商`providers` | 导出什么 | 被谁导入 | 范例 |
---|---|---|---|---|---|
领域 | 有 | 罕见 | 顶级组件 | 特性模块和 | |
路由 | 有 | 罕见 | 无 | 无 | |
路由 | 无 | 有 | 无 | | |
服务 | 无 | 有 | 无 | | |
窗口部件 | 有 | 罕见 | 有 | 特性模块 | |