有人能解释一下SharedModuleCoreModule是什么意思吗?

我已经观察到有几个项目正在使用这种方法来构建它的Angular 项目.

  1. 为什么我需要两个模块?
  2. 我应该什么时候导入每一个?
  3. 每个人应该有哪个importsexportsdeclarations

推荐答案

TLDR:

  1. 核心模块应该只有services,并且只能在AppModule中导入一次.
  2. 共享模块应该有services以外的任何东西,并在所有需要共享内容(也可以是AppModule)的模块中导入.

但是:

现实世界的模块通常是有意偏离[上述]指导原则的混合模块.这些指导方针不是法律;除非你有充分的理由go 做,否则就跟着他们go 做.


RTFM:

所以,在浏览了整个NgModules' docs篇文章(加上一些其他的东西来理解上下文)之后,我很容易找到了the answer for your 2nd and 3rd questions

共享模块

  • 用你的应用程序中随处可见的componentsdirectivespipes创建一个共享模块.此模块应完全由declarations个模块组成,其中大部分已导出.
  • 共享模块可能会重新导出其他小部件模块,如CommonModuleFormsModule,以及您使用最广泛的UI控件的模块.
  • 出于前面解释的原因,共享模块人不应该有providers人.它的任何导入或再导出的模块也不应该有提供程序.如果你偏离了这个指导方针,知道你在做什么以及为什么.
  • 在您的功能模块中导入共享模块,无论是在应用程序启动时加载的功能模块,还是您稍后懒惰加载的功能模块.

核心模块

  • 为应用程序启动时加载的单例服务创建核心模块providers.
  • 仅在根AppModule中导入核心模块.切勿在任何其他模块中导入核心模块.
  • 考虑核心模块做一个纯服务模块,没有declarations.

虽然这些比上面的TLDR版本更详细,您现在可以继续并继续编码,但它提到了一些您必须阅读文档才能理解的内容(即"小部件模块"、"前面解释的原因"、"纯服务模块"),以及doesn't answer your 1st question.

所以让我们试着做到这一点!


为什么我需要两个模块?

你有两个模块.以下是文档中的内容:

在一个只有几个组件的简单应用程序中,根模块就是您所需要的全部.

话虽如此,首先提出一个不同的问题很重要:

为什么人们要将他们的项目组织成多个模块?

关于这一点的基本解释就在文件中的上述声明之后:

随着应用程序的增长,您可以将根模块重构为表示相关功能集合的功能模块.然后将这些模块导入根模块.

但你问"为什么?"这需要的不仅仅是一个基本的解释.因此,让我们开始解释如果你的应用开始增长,并将don't separate项功能添加到功能模块中,可能会发生的problems多种情况:

  • 根模块开始变得杂乱无章,代码很难阅读和使用,因为它必须导入所有依赖项(例如第三方模块)、提供所有服务并声明所有组件、指令和管道.应用程序需要的越多,这个模块就越大.
  • 不同的功能之间没有明确的界限,这使得理解应用程序的 struct 以及在团队中承担不同的责任变得更加困难.
  • 你可以开始解决应用程序不同部分之间的冲突.例如,如果在应用程序的两个不同部分中有执行相同操作的指令或组件,则必须开始使用更长的名称来区分它们,或者在导入时重命名它们.

虽然你可能认为上面的例子并不完全是问题(也许你独自工作,可以忍受你自己的混乱,或者你所有的队友也是凌乱的),但请记住,其他人肯定不会同意你的观点,这就是你"have been watching several project[s] out there ... using this approach"岁的原因.

考虑到您同意这一点,并希望将不断增长的应用程序组织成功能模块,请注意文档中的以下声明:

根模块和功能模块共享相同的执行上下文.它们共享相同的依赖项注入器,这意味着一个模块中的服务对所有人都可用.

这些模块具有以下重大技术差异:

  • 启动根模块以启动应用程序;导入功能模块以扩展应用程序.
  • 功能模块可以向其他模块公开或隐藏其实现.

Information to never forget: "services in one module are available to all [modules]", while other things, like Components, Directives, and Pipes must be injected in each module that wants to use them.

有了这些信息,我们现在可以通过回答以下问题更接近您想要了解的内容:

Are all feature modules equal?

NO!至少有人建议它们不应该相等,因为有人建议你不应该只有根模块,但你可以做任何你想做的事.但你不应该.

文档中有一个表格,显示了建议的功能模块组之间的差异.让我们看看它的摘录:

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             

请注意!他们说得很清楚这是一个...

...基于早期使用经验的初步指导

所以,再一次,你没有坚持这个指导方针,可能会发生偏差,但你应该知道你在做什么,为什么.

现在让我们分析一下这个表:

  • 只有Service组和Widget组在每列中的值完全不同.
  • Domain组和Routed组与Widget组基本相同,只是出口有限或没有出口.
  • Routing组基本上是Service组,但有一个导出例外,并且限于特定的提供者.

因此,让我们考虑Domain, RoutedRouting组只是ServiceWidget的变型,并集中在最后两个.

应该引起你的注意.请记住,您永远不要忘记"一个模块中的服务可供所有[模块]使用"?如果他们称一个功能模块组为Services,那是因为它必须与其他模块隔离,所以只能导入一次.例如,您可以有一个UserModule,它由SignUpServiceSignInServiceSocialAuthServiceUserProfileService等服务组成.无论你在哪里导入UserModule,它的所有服务都将在应用程序范围内可用.根据上表,它不应该有申报或出口,只有供应商.

Widgets听起来更通用,但它应该告诉你一些事情.记住,你也永远不要忘记这一点?所以这就是你将用于这些的模块类型.例如,你可以把UIModuleButtonComponentNavComponentSlideshowComponentHighlightLinkDirectiveCtaPipe结合起来.每次需要使用一个或所有导出的元素时,只需导入UIModule个.

因此,基本上,由于Angular处理服务的方式,当您开始将功能划分为功能模块时,您必须将服务分离为它们自己的模块,而其他内容可以按照您的意愿在它们之间进行组织.

How do 100 and 101 fit into this?

为简单起见,核心模块Service模块,共享模块Widget模块.这就是为什么您应该在AppModule中只导入第一个,在所有需要它的模块中导入后一个.从上面的示例中,UserModule将由核心模块导入,UIModule将由共享模块导入.

但是,如前所述,这些是指导方针,可能会发生偏差,即使在他们自己的示例中,他们也声明了核心模块中的组件,但有一个观察:

此页面示例与该建议不同,声明并导出[核心模块]两个组件,这两个组件仅在AppModule声明的根AppComponent中使用.严格遵循这条准则的人会在AppModule中声明这些组件.


就我个人而言,我认为最大的困惑是关于命名的 Select .一般来说,人们会认为你的应用程序核心部分的所有内容(即用户资料、导航栏、加载栏、 toastr 等)都会进入核心模块,多个功能共享的所有内容都会进入共享模块.

事实并非如此,而且有点误导,因为所有服务"本质上"在所有模块之间共享,共享模块中不应包含任何服务,NavbarComponent是应用程序核心的一部分,核心模块中不应包含任何组件.

在任何情况下,建议遵循指南,直到你找到不这样做的理由.

为了更好地理解指导方针,以下是上表的睡觉:

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, 核心模块
Widget    Feature                CommonModule, 共享模块

干杯!

Angular相关问答推荐

Angular:浏览器中未显示一些Google Content图标

如何在@angular/material-experimental中使用自定义调色板-Expeded $connect.Color.primary将成为有效的M3调色板

仅在展示时使用垫式步进器

AG网格Angular 快捷菜单调用函数

在Angular 应用中混合使用较少和较粗俗的文件

如何使用解析器处理Angular 路由中存储的查询参数以避免任何额外的导航?

当try 关闭浏览器选项卡时显示alert 时,我是否可以捕获用户是否取消警告

MAT折叠面板的动态开启和关闭无法工作

升级到 Webpack 5.79.0 后 NX Angular 项目构建失败

Angular 13 - 使用 PUT 时出现 400 错误(错误请求)

Storybook 和 Angular 交互游戏测试未定义预期

正确理解 angular14 中的注入 - 必须从注入上下文中调用注入()

为什么 Redux 中的对象应该是不可变的?

res.json() 不是函数

当父组件上的变量发生变化时重新加载子组件

Angular2 - 如何开始以及使用哪个 IDE

Angular 2:为什么在检索路由参数时使用 switchMap?

Angular Material2 主题 - 如何设置应用程序背景?

Angular 2 输出到router-outlet

从 Angular 中的自定义表单组件访问 FormControl