我一直在观察几个使用这种方法的项目,以便建立它的角度项目.
>为什么我需要两个模块?
>我什么时候应该导入每一个?
>每个人应该拥有哪些进口,出口,报关单?
> CoreModule应该只有服务,并且只能在AppModule中导入一次.
> SharedModule应该只有服务,并且可以在需要共享内容的所有模块中导入(也可以是AppModule).
但:
Real-world modules are often hybrids that purposefully deviate from the [above] guidelines. These guidelines are not laws; follow them unless you have a good reason to do otherwise.
RTFM:
所以,在完成整个NgModules’ docs(加上其他一些东西以了解背景)后,我很容易找到第2和第3个问题的答案
there.他们是:
SharedModule
- Create a
SharedModule
with thecomponents
,directives
,andpipes
that you use everywhere in your app. This module should consist entirely ofdeclarations
,most of them exported.- The
SharedModule
may re-export other widget modules,such asCommonModule
,FormsModule
,and modules with the UI controls that you use most widely.- The
SharedModule
should not haveproviders
for reasons explained prevIoUsly. Nor should any of its imported or re-exported modules have providers. If you deviate from this guideline,know what you’re doing and why.- Import the
SharedModule
in your feature modules,both those loaded when the app starts and those you lazy load later.
CoreModule
- Create a
CoreModule
withproviders
for the singleton services you load when the application starts.- Import
CoreModule
in the rootAppModule
only. Never importCoreModule
in any other module.- Consider making
CoreModule
a pure services module with nodeclarations
.
虽然这些比上面的TLDR版本更详细,但您现在可以继续编码,但它提到了一些您必须阅读文档才能理解的内容(即“小部件模块”,“之前解释的原因”,“纯服务模块” “),它也没有回答你的第一个问题.
所以让我们试着这样做!
为什么我需要两个模块?
您不需要两个模块.这是文档中的内容:
The root module is all you need in a simple application with a few components.
话虽如此,首先提出一个不同的问题很重要:
为什么人们将项目组织成多个模块?
对此的基本解释恰好在文档中的上述声明之后:
As the app grows,you refactor the root module into feature modules that represent collections of related functionality. You then import these modules into the root module.
但你问“为什么?”这需要的不仅仅是基本的解释.因此,让我们开始解释如果您的应用程序开始增长并且您没有将功能分离到功能模块中可能会出现的问题:
>根模块开始变得混乱,代码难以阅读和使用,因为它必须导入所有依赖项(例如第三方模块),提供所有服务并声明所有组件,指令和管道.应用程序需要的越多,该模块就越大.
>不同的功能在它们之间没有明确的界限,使得更难以理解应用程序的结构,而且对团队负有不同的责任.
>您可以开始解决应用程序不同部分之间的冲突.例如,如果您的指令或组件在应用程序的两个不同部分中执行相同操作,则您必须开始使用较长的名称来区分它们或在导入时重命名它们.
虽然你可能认为上面的例子不是问题(也许你独自工作,可以和你自己的混乱一起生活,或者你的所有队友都很混乱),但请记住,其他人肯定不同意你,这就是为什么你“一直在那里观看几个项目……使用这种方法”.
考虑到您同意并希望将不断增长的应用程序组织到功能模块中,请注意以下文档中的声明:
The root module and the feature module share the same execution context. They share the same dependency injector,which means the services in one module are available to all.
The modules have the following significant technical differences:
- You boot the root module to launch the app; you import a feature module to extend the app.
- A feature module can expose or hide its implementation from other modules.
永远不会忘记的信息:“一个模块中的服务可供所有[模块]”使用,而其他内容(如组件,指令和管道)必须注入每个想要使用它们的模块中.
通过这些信息,我们现在可以通过回答以下问题更接近您想要了解的内容:
所有功能模块都相同吗?
没有!至少建议他们不应该是平等的,因为建议你不应该只有根模块,但你可以做任何你想做的事情.但你不应该.
文档有一个表格,显示建议的功能模块组之间的差异.我们来看一下它的摘录:
FEATURE SHOULD HAVE SHOULD HAVE SHOULD HAVE MODULE DECLARATIONS PROVIDERS EXPORTS Domain Yes Rare Top component Routed Yes Rare No Routing No Yes (Guards) RouterModule Service No Yes No Widget Yes Rare Yes
注意!他们很清楚这是……
…preliminary guidance based on early experience using
NgModules in a few applications.
所以,再次,你不会坚持这个指导方针,并且可能会发生偏差,但你应该知道你正在做什么以及为什么.
现在让我们分析一下这个表:
> Service和Widget组是每个列中唯一具有完全不同值的组.
> Domain和Routed组与Widget组基本相同,只有有限或无出口.
>路由组基本上是一个服务组,具有导出异常并且仅限于特定提供程序.
所以,让我们考虑Domain,Routed和Routing组只是Service或Widget的变体,并关注最后两个.
服务应该引起你的注意.请记住,您永远不应忘记“一个模块中的服务可用于所有[模块]”?好吧,如果他们调用功能模块组服务,那是因为它必须与其他模块隔离,因此只能导入一次.例如,您可以拥有一个UserModule,它包含SignUpService,SignInService,SocialAuthService和UserProfileService等服务.无论您在何处导入该UserModule,其所有服务都将在应用程序范围内可用.根据上表,它不应该只有提供者的声明和出口.
小部件听起来更通用,但它应该告诉你一些东西.请记住,您也应该永远不要忘记“其他内容,例如组件,指令和管道必须注入每个想要使用它们的模块中.”?所以这是你将用于那些模块的类型.例如,您可以使用带有ButtonComponent,NavComponent,SlideshowComponent,HighlightLinkDirective,CtaPipe的UIModule.每次需要使用其中一个或所有导出的元素时,只需导入UIModule.
因此,基本上,由于Angular处理服务的方式,当您开始将功能划分为功能模块时,您必须将服务隔离到自己的模块中,而其他内容可以根据您的需要在它们之间进行组织.
CoreModule和SharedModule如何适应这个?
为了简单起见,CoreModule是一个服务模块,而SharedModule是一个Widget模块.这就是为什么你应该在AppModule中只导入一次,而在需要它的所有模块中导入后者.从上面的示例中,UserModule将由CoreModule导入,而UIModule将由SharedModule导入.
但是,如前所述,这些是指导方针,即使在他们自己的示例中,他们也在CoreModule中声明了组件,但有一个观察结果:
This page sample departs from that advice by declaring and exporting [in the
CoreModule
] two components that are only used within the root AppComponent declared by AppModule. Someone following this guideline strictly would have declared these components in the AppModule instead.
就个人而言,我认为最大的困惑在于命名选择.一般来说,人们会认为应用程序核心的所有内容(即用户资料,导航栏,加载栏,烤面包机等)都将进入CoreModule,并且跨多个功能共享的所有内容都将进入SharedModule.
这实际上并不是真的有点误导,因为所有服务都是“本质上”在所有模块之间共享,并且SharedModule中不应包含任何服务,以及NavbarComponent是应用程序核心的一部分,不应包含任何组件在CoreModule中.
无论如何,建议遵循指南,直到找到不这样做的理由.
以上表格的其余部分有助于更好地理解指南:
FEATURE CAN BE SOME MODULE IMPORTED BY EXAMPLES Domain Feature,AppModule ContactModule (before routing) Routed Nobody ContactModule,DashboardModule,Routing Feature (for routing) AppRoutingModule,ContactRoutingModule Service AppModule HttpModule,CoreModule Widget Feature CommonModule,SharedModule
干杯!