NgModule

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. 特性模块
围绕特定的业务领域、工作流和工具集来为应用创建特性模块。特性模块一般可分成下面这几种:
领域特性模块。
带路由的特性模块
路由模块
服务特性模块
窗口部件特性模块

特性模块

指导原则

领域

领域特性模块专注于一个特定的应用领域来提供用户体验,比如编辑消费者信息或下订单。

它们通常有一个顶级组件,并作为该特性的根组件。 内部则是它的一些子组件。

领域特性模块几乎总是由declarations构成。只有顶级组件会被导出。

领域特性模块很少会有providers。 如果要这么做,那它们所提供服务的生命周期就应该与该模块的生命周期相同。

不要在领域特性模块中提供全应用级的单例服务。

领域特性模块的典型用法是只被更大的特性模块导入一次

对于缺少路由的小型应用,它们可能只会被根模块AppModule导入一次。

路由特性模块

路由特性模块属于领域特性模块的一种,它的顶层组件是路由器导航时的路由目标。

根据这个定义,所有惰性加载的模块都是路由特性模块。

这里的ContactModuleHeroModuleCrisisModule都是路由特性模块。

路由特性模块不应该导出任何东西,这是因为它们中的任何组件都不可能出现在外部组件的模板中。

惰性加载的路由特性模块也不应该被任何模块导出。 那么做会触发一次主动加载,破坏了我们惰性加载的目的。HeroModuleCrisisModule是惰性加载的。它们没有出现在AppModuleimports中。

而主动加载的路由特性模块必须被其它模块导入,以便编译器了解它有哪些组件。 ContactModule就是主动加载的,因此它也被列在了AppModuleimports中。

路由特性模块很少会有providers,理由前面解释过。 如果要那么做,它所提供的服务就应该与模块具有相同的生命周期。

不要在路由特性模块及其导入的模块中提供全应用级的单例服务。

路由模块

路由模块为其它模块提供路由配置。

路由模块将路由配置从它的关联模块分离开来。

路由模块通常会做这些:

定义路由。

添加路由配置到模块的imports中。

重新导出RouterModule

添加守卫和解析器服务提供商到模块的providers

路由模块的名字应该和它的关联模块平行,比如使用“Routing”前缀, foo.module.ts中的FooModule有名为FooRoutingModule的路由模块,所属文件名为foo-routing.module.ts

如果关联模块是根AppModule,那么在AppRoutingModuleimports中,添加RouterModule.forRoot(routes)来配置路由。 所有其它路由模块都是子级,导入RouterModule.forChild(routes)

路由模块顺便重新导出RouterModule,这样关联模块的组件可以访问路由指令,比如RouterLinkRouterOutlet

路由模块不应该有自己的declarations!。组件、指令和管道是特性模块的责任,不属于路由模块。

路由模块应该只被它的关联模块导入。

AppRoutingModuleContactRoutingModule和`HeroRoutingModule是很好的例子。

参见路由与导航一章的“你需要路由模块吗?”部分。

服务

服务模块用于提供工具类服务,比如数据访问和消息等。

理想情况下,它们应该完全由providers组成,不应该包括declarations。 CoreModule和Angular的HttpModule就是很好的例子。

服务模块应该只被根模块AppModule导入。

不要在任何特性模块中导入它们。 如果你要违背这条指导原则,请务必想清楚你在做什么,并要有充分的理由。

窗口部件

窗口部件模块导出能用供外部模块使用的组件、指令和管道。

CommonModuleSharedModule都是窗口部件模块。 很多第三方UI组件库都是窗口部件模块。

部件模块应该只有declarations,并导出里面的绝大多数声明。

窗口部件模块很少会有providers。 如果你要违背这条指导原则,请务必想清楚你在做什么,并要有充分的理由。

如果任何模块的组件模板中需要用到这些窗口部件,就请导入相应的窗口部件模块。

特性模块

声明`declarations`

提供商`providers`

导出什么

被谁导入

范例

领域

罕见

顶级组件

特性模块和AppModule

ContactModule(路由之前的那个例子)

路由

罕见

ContactModuleHeroModuleCrisisModule

路由

AppModule

AppModule

HttpModuleCoreModule

服务

AppModule

AppModule

HttpModuleCoreModule

窗口部件

罕见

特性模块

CommonModuleSharedModule

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值