模块(NgModule)创建指南
Guidelines for creating NgModules
本主题提供了一个概念性的概述,讲的是你可以创建不同类别的模块 使用模块化结构来组织代码。这些类别并不是一成不变的,而是建议性的。你可能想为其他目的创建模块,或者把其中某些类别的特征结合在一起。
This topic provides a conceptual overview of the different categories of NgModules you can create in order to organize your code in a modular structure. These categories are not cast in stone—they are suggestions. You may want to create NgModules for other purposes, or combine the characteristics of some of these categories.
模块是组织应用的好办法,可以让与特定功能或特性有关的代码与其他代码分开。可以使用模块把组件,指令和管道整合成一些内聚的代码块。专注于某项功能或业务领域、工作流程或导航流程、通用工具集,或者一个或多个服务提供者。
NgModules are a great way to organize an app and keep code related to a specific functionality or feature separate from other code. Use NgModules to consolidate components, directives, and pipes into cohesive blocks of functionality. Focus each block on a feature or business domain, a workflow or navigation flow, a common collection of utilities, or one or more providers for services.
关于模块的更多信息,请参阅使用模块组织你的应用。
For more about NgModules, see Organizing your app with NgModules.
要获得模块相关主题中使用的范例应用,参阅
For the example app used in NgModules-related topics, see the
模块类别汇总
Summary of NgModule categories
所有的应用都是从引导一个根模块开始的。你可以按照自己喜欢的方式组织其它模块。
All apps start by bootstrapping a root NgModule. You can organize your other NgModules any way you wish.
本主题为下列常见模块类别提供了一些指导:
This topic provides some guidelines for the following general categories of NgModules:
领域模块:领域模块围绕特性、业务领域或用户体验进行组织。
Domain: A domain NgModule is organized around a feature, business domain, or user experience.
带路由的模块:模块的顶层组件充当路由器访问这部分路由时的目的地。
Routed: The top component of the NgModule acts as the destination of a router navigation route.
路由配置模块:路由配置模块为另一个模块提供路由配置。
Routing: A routing NgModule provides the routing configuration for another NgModule.
服务模块:服务模块提供实用服务,比如数据访问和消息传递。
Service: A service NgModule provides utility services such as data access and messaging.
小部件:小部件模块可以为其它模块提供某些组件、指令或管道。
Widget: A widget NgModule makes a component, directive, or pipe available to other NgModules.
共享模块:共享模块可以为其它的模块提供组件,指令和管道的集合。
Shared: A shared NgModule makes a set of components, directives, and pipes available to other NgModules.
下表总结了每个类别的主要特性。
The following table summarizes the key characteristics of each category.
模块 NgModule | 可声明对象 Declarations | 提供者 Providers | 导出 Exports | 被谁导入 Imported by |
---|---|---|---|---|
领域模块 Domain | 是 Yes | 罕见 Rare | 顶级组件 Top component | 其它领域模块、根模块 Another domain, AppModule |
带路由的模块 Routed | 是 Yes | 罕见 Rare | 否 No | 无 None |
路由定义模块 Routing | 否 No | 是 (路由守卫) Yes (Guards) | RouterModule | 其它领域模块(为获取路由定义) Another domain (for routing) |
服务模块 Service | 否 No | 是 Yes | 否 No | AppModule |
小部件模块 Widget | 是 Yes | 罕见 Rare | 是 Yes | 其它领域模块 Another domain |
共享模块 Shared | 是 Yes | 否 No | 是 Yes | 其它领域模块 Another domain |
领域模块
Domain NgModules
使用领域模块来提供专属于特定功能或应用领域的界面,比如编辑客户或下单。例子之一是ContactModule
。
Use a domain NgModule to deliver a user experience dedicated to a particular feature or app domain, such as editing a customer or placing an order. One example is ContactModule
in the
领域模块用来组织与特定功能有关的代码,里面包含构成此功能的所有组件、路由和模板。领域模块中的顶级组件是该特性或领域的根,是你要导出的唯一组件。各种私有的支撑子组件都是它的后代。
A domain NgModule organizes the code related to a certain function, containing all of the components, routing, and templates that make up the function. Your top component in the domain NgModule acts as the feature or domain's root, and is the only component you export. Private supporting subcomponents descend from it.
领域模块要导入到另一个模块中一次并且只能一次,比如一个领域模块,或者一个只包含少量模块的应用的根模块(AppModule
)中。
Import a domain NgModule exactly once into another NgModule, such as a domain NgModule, or into the root NgModule (AppModule
) of an app that contains only a few NgModules.
领域模块主要由可声明对象组成,很少会在此提供服务。如果一定要提供,那么这些服务的生命周期应和该模块的生命周期一致。
Domain NgModules consist mostly of declarations. You rarely include providers. If you do, the lifetime of the provided services should be the same as the lifetime of the NgModule.
关于生命周期的详细信息,请参阅“组件生命周期钩子” 。
For more information about lifecycles, see Hooking into the component lifecycle.
带路由的模块
Routed NgModules
所有惰性加载模块都要用带路由的模块。使用该模块的顶级组件作为路由器导航路由的目标。带路由的模块不会导出任何内容,因为它们的组件永远不会出现在外部组件的模板中。
Use a routed NgModule for all lazy-loaded NgModules. Use the top component of the NgModule as the destination of a router navigation route. Routed NgModules don’t export anything because their components never appear in the template of an external component.
不要把惰性加载的带路由的模块导入到另一个模块中,因为这会触发一个急性加载,从而破坏了惰性加载它的目的。
Don't import a lazy-loaded routed NgModule into another NgModule, as this would trigger an eager load, defeating the purpose of lazy loading.
带路由的模块很少有提供者,因为你只在需要的时候加载带路由的模块(例如通过路由导航过来时)。 provider
数组中列出的服务不可用,因为根注入器不可能预先知道惰性加载的模块。如果你包含了提供者,那么它们所提供的服务的生命周期应该和该模块的生命周期完全一样。不要在带路由的模块及其导入的相关模块中提供全应用范围内的单例服务。。
Routed NgModules rarely have providers because you load a routed NgModule only when needed (such as for routing). Services listed in the NgModules' provider
array would not be available because the root injector wouldn’t know about the lazy-loaded NgModule. If you include providers, the lifetime of the provided services should be the same as the lifetime of the NgModule. Don't provide app-wide singleton services in a routed NgModule or in an NgModule that the routed NgModule imports.
关于服务提供者和惰性加载的带路由模块的更多信息,请参阅限制提供者的范围。
For more information about providers and lazy-loaded routed NgModules, see Limiting provider scope.
路由定义模块
Routing NgModules
使用路由定义模块来为领域模块提供路由配置,从而将路由相关的关注点从其伴生领域模块中分离出来。例子之一是ContactRoutingModule
,它为其伴生领域模块 ContactModule
提供路由。
Use a routing NgModule to provide the routing configuration for a domain NgModule, thereby separating routing concerns from its companion domain NgModule. One example is ContactRoutingModule
in theContactModule
.
关于路由定义的概述和详细信息,请参阅应用内导航:路由到视图。
For an overview and details about routing, see In-app navigation: routing to views.
使用路由定义模块来完成如下任务:
Use a routing NgModule to do the following tasks:
定义路由。
Define routes.
把路由器配置文件添加到模块的导入表中。
Add router configuration to the NgModule's import.
往模块的提供者列表中添加路由守卫和解析器(resolver)提供者。
Add guard and resolver service providers to the NgModule's providers.
路由定义模块的名字应该和其伴生模块的名字平行,但使用 Routing
后缀。例如, contact.module.ts
中的 ContactModule
有一个位于 contact-routing.module.ts
中的名为 ContactRoutingModule
的路由定义模块。
The name of the routing NgModule should parallel the name of its companion NgModule, using the suffix Routing
. For example, ContactModule
in contact.module.ts
has a routing NgModule named ContactRoutingModule
in contact-routing.module.ts
.
路由定义模块只能导入它的伴生模块中。如果伴生模块是根模块 AppModule
,那么 AppRoutingModule
就会通过其导入表中的 RouterModule.forRoot(routes)
来添加路由器配置。所有其他的子路由定义模块都会导入 RouterModule.forChild(routes)
。
Import a routing NgModule only into its companion NgModule. If the companion NgModule is the root AppModule
, the AppRoutingModule
adds router configuration to its imports with RouterModule.forRoot(routes)
. All other routing NgModules are children that import RouterModule.forChild(routes)
.
在路由定义模块中,要重新导出 RouterModule
,以便其伴生模块中的组件可以访问路由器指令,比如 RouterLink
和 RouterOutlet
。
In your routing NgModule, re-export the RouterModule
as a convenience so that components of the companion NgModule have access to router directives such as RouterLink
and RouterOutlet
.
不要在路由定义模块中使用可声明对象。组件、指令和管道都是伴生领域模块的责任,而不是路由定义模块的。
Don't use declarations in a routing NgModule. Components, directives, and pipes are the responsibility of the companion domain NgModule, not the routing NgModule.
服务模块
Service NgModules
使用服务模块来提供实用工具服务,比如数据访问或消息传递。理想的服务模块完全由提供者组成,没有可声明对象。 Angular 的 HttpClientModule
是服务模块的一个典范。
Use a service NgModule to provide a utility service such as data access or messaging. Ideal service NgModules consist entirely of providers and have no declarations. Angular's HttpClientModule
is a good example of a service NgModule.
只能使用根模块 AppModule
来导入各种服务模块。
Use only the root AppModule
to import service NgModules.
小部件模块
Widget NgModules
使用小部件模块可以把组件、指令或管道提供给外部模块使用。把小部件模块导入到任何需要在模板使用这些小部件的模块中。很多第三方 UI 组件库都是作为小部件模块提供的。
Use a widget NgModule to make a component, directive, or pipe available to external NgModules. Import widget NgModules into any NgModules that need the widgets in their templates. Many third-party UI component libraries are provided as widget NgModules.
小部件模块应该完全由可声明对象组成,其中大部分都是导出的。服务提供者非常罕见。
A widget NgModule should consist entirely of declarations, most of them exported. It would rarely have providers.
共享模块
Shared NgModules
把常用的指令、管道和组件放到一个模块中,通常叫做 SharedModule
,然后在应用的其他部分只需要导入这个模块就可以了。你可以在领域模块(包括惰性加载模块)中导入共享模块。例子之一就是SharedModule
,它提供了自定义管道 AwesomePipe
和 HighlightDirective
指令。
Put commonly used directives, pipes, and components into one NgModule, typically named SharedModule
, and then import just that NgModule wherever you need it in other parts of your app. You can import the shared NgModule in your domain NgModules, including lazy-loaded NgModules. One example is SharedModule
in theAwesomePipe
custom pipe and HighlightDirective
directive.
共享模块不应该包含服务提供者,它所导入或重新导出的任何模块也都不应该包含提供者。
Shared NgModules should not include providers, nor should any of its imported or re-exported NgModules include providers.
要了解如何使用共享模块来组织和简化代码,请参阅在应用中使用共享模块 。
To learn how to use shared modules to organize and streamline your code, see Sharing NgModules in an app.
下一步
Next steps
你可能也对下列内容感兴趣:
You may also be interested in the following:
关于 Angular 模块的更多信息,请参阅使用模块组织你的应用。
For more about NgModules, see Organizing your app with NgModules.
要了解关于根模块的更多信息,请参阅使用根模块启动应用。
To learn more about the root NgModule, see Launching an app with a root NgModule.
要了解最常使用的那些 Angular 模块,以及如何将它们导入你的应用,请参阅常用模块。
To learn about frequently used Angular NgModules and how to import them into your app, see Frequently-used modules.
关于模块元数据属性的完整描述,请参阅使用模块元数据。
For a complete description of the NgModule metadata properties, see Using the NgModule metadata.
如果你想管理模块的加载以及依赖和服务的使用,参阅下列内容:
If you want to manage NgModule loading and the use of dependencies and services, see the following:
要了解如何在应用启动时急性加载模块,或者让路由器异步加载模块,请参阅惰性加载特性模块。
To learn about loading NgModules eagerly when the app starts, or lazy-loading NgModules asynchronously by the router, see Lazy-loading feature modules.
要了解如何为你的应用提供服务或其它依赖,请参阅为模块提供依赖。
To understand how to provide a service or other dependency for your app, see Providing Dependencies for an NgModule.
要了解如何在模块中创建单例服务,请参阅“使服务成为单例” 。
To learn how to create a singleton service to use in NgModules, see Making a service a singleton.