ChatGPT解决这个技术问题 Extra ChatGPT

NgModule 中的声明、提供者和导入有什么区别?

我试图了解 Angular(有时称为 Angular2+),然后遇到了 @Module

进口申报供应商

关注Angular Quick Start


1
1252748

角度概念

导入使当前模块中其他模块的导出声明可用

声明是为了使当前模块中的指令(包括组件和管道)可用于当前模块中的其他指令。指令、组件或管道的选择器仅在声明或导入时才与 HTML 匹配。

提供者将让 DI(依赖注入)知道服务和值。它们被添加到根作用域,并被注入到将它们作为依赖项的其他服务或指令中。

providers 的一个特例是延迟加载模块,它们有自己的子注入器。 providers 的延迟加载模块默认情况下仅提供给该延迟加载模块(而不是整个应用程序,因为它与其他模块一样)。

有关模块的更多详细信息,另请参阅 https://angular.io/docs/ts/latest/guide/ngmodule.html

导出使组件、指令和管道在将此模块添加到导入的模块中可用。导出也可用于重新导出模块,例如 CommonModule 和 FormsModule,这通常在共享模块中完成。

entryComponents 为离线编译注册组件,以便它们可以与 ViewContainerRef.createComponent() 一起使用。路由器配置中使用的组件是隐式添加的。

TypeScript (ES2015) 导入

import ... from 'foo/bar'(其中 may resolve to an index.ts)用于 TypeScript 导入。每当您在另一个打字稿文件中声明的打字稿文件中使用标识符时,您都需要这些。

Angular 的 @NgModule() imports 和 TypeScript import完全不同的概念

另请参阅jDriven - TypeScript and ES6 import syntax

它们中的大多数实际上是 TypeScript 也使用的纯 ECMAScript 2015 (ES6) 模块语法。


我认为,但我不确定,最新的建议是将应用程序范围的提供程序放在 CoreModule 中,而不是在延迟加载的模块中使用 forRoot()。你同意吗?请参阅The Core Module。 #shared-module-for-root 的链接不再存在。
很好的解释。谢谢你,@günter-zöchbauer。仅提及 afaik import 是 JS (ES2015) 功能,不是 TypeScript 功能。 :)
什么是 NgModule 中的 export [] 就像 export 一样糟糕:[MatCheckBox]
说实话,我觉得 Angular 的 NgModule 的设计与 VueReact 相比是笨拙和晦涩的。您需要使用 imports 导入其他模块,但使用 exports 导出您的可声明(组件、指令、管道)。因此,importsexports 的主要目标是不同的东西。相反,exports 的主要目标是您的 declarations。您通过 declarations 声明您的组件,但是对于动态加载的组件,您需要将它们放在 entryComponents 中。与此同时,providers 由 DI 在另一个故事中管理。
描述复杂框架的复杂答案
G
Godfather

imports 用于导入支持模块,如 FormsModule、RouterModule、CommonModule 或任何其他自定义功能模块。

declarations 用于声明属于当前模块的组件、指令、管道。声明中的每个人都互相认识。例如,如果我们有一个组件,比如 UsernameComponent,它显示用户名列表,我们还有一个管道,比如 toupperPipe,它将字符串转换为大写字母字符串。现在,如果我们想在 UsernameComponent 中以大写字母显示用户名,那么我们可以使用我们之前创建的 toupperPipe,但问题是 UsernameComponent 如何知道 toupperPipe 存在以及它如何访问和使用它。声明来了,我们可以声明 UsernameComponent 和 toupperPipe。

Providers 用于注入模块中组件、指令、管道所需的服务。


“声明:用于声明属于当前模块的组件、指令、管道。声明中的所有内容都相互认识。”这应该是公认的答案
J
John Henckel

声明组件,导入模块,并提供服务。我正在使用的一个例子:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';


import { AppComponent } from './app.component';
import {FormsModule} from '@angular/forms';
import { UserComponent } from './components/user/user.component';
import { StateService } from './services/state.service';    

@NgModule({
  declarations: [
    AppComponent,
    UserComponent
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [ StateService ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

我喜欢这个解释的简单性,但它让我想知道为什么不只有一个“stuffsThisComponentNeeds”属性?似乎他们都在处理同样的事情,这使得其他代码片段可用于当前组件。
@redOctober13 我同意。例如,在 Node.js 中,无论是数据库模型、模块、服务还是安装的 3rd 方包,所有内容都以相同的方式导入。我认为 reactJS 也会发生同样的情况
P
Przemek Struciński

添加一个快速备忘单,在长时间使用 Angular 后可能会有所帮助:

声明

例子:

declarations: [AppComponent]

我们可以在这里注入什么?组件、管道、指令

进口

例子:

imports: [BrowserModule, AppRoutingModule]

我们可以在这里注入什么?其他模块

供应商

例子:

providers: [UserService]

我们可以在这里注入什么?服务

引导程序

例子:

bootstrap: [AppComponent]

我们可以在这里注入什么?该模块将生成的主要组件(组件树的顶部父节点)

入口组件

例子:

entryComponents: [PopupComponent]

我们可以在这里注入什么?动态生成的组件(例如通过使用 ViewContainerRef.createComponent())

出口

例子:

export: [TextDirective, PopupComponent, BrowserModule]

我们可以在这里注入什么?我们希望在另一个模块中访问它们的组件、指令、模块或管道(在导入此模块后)


出口呢?
@lugte098 我已将导出添加到此列表中
我喜欢这种解释的布局,非常容易消化。谢谢!
W
Willem van der Veen

Angular @NgModule 构造:

import { x } from 'y';:这是从其他文件导入代码的标准打字稿语法(ES2015/ES6 模块语法)。这不是 Angular 特定的。此外,这在技术上不是模块的一部分,只需要在此文件范围内获取所需的代码。导入:[FormsModule]:您在此处导入其他模块。例如,我们在下面的示例中导入 FormsModule。现在我们可以使用 FormsModule 在整个模块中提供的功能。声明: [OnlineHeaderComponent, ReCaptcha2Directive]:您将组件、指令和管道放在这里。一旦在这里声明,您现在可以在整个模块中使用它们。例如,我们现在可以在 AppComponent 视图(html 文件)中使用 OnlineHeaderComponent。 Angular 知道在哪里可以找到这个 OnlineHeaderComponent,因为它是在 @NgModule 中声明的。 providers: [RegisterService]: 这里定义了我们这个特定模块的服务。您可以通过依赖注入来使用组件中的服务。

示例模块:

// Angular
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

// Components
import { AppComponent } from './app.component';
import { OfflineHeaderComponent } from './offline/offline-header/offline-header.component';
import { OnlineHeaderComponent } from './online/online-header/online-header.component';

// Services
import { RegisterService } from './services/register.service';

// Directives
import { ReCaptcha2Directive } from './directives/re-captcha2.directive';

@NgModule({
  declarations: [
    OfflineHeaderComponent,,
    OnlineHeaderComponent,
    ReCaptcha2Directive,
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
  ],
  providers: [
    RegisterService,
  ],
  entryComponents: [
    ChangePasswordComponent,
    TestamentComponent,
    FriendsListComponent,
    TravelConfirmComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Y
Yogesh Waghmare

声明:此属性说明属于此模块的组件、指令和管道。导出:应该在其他 NgModule 的组件模板中可见和可用的声明子集。导入:在此 NgModule 中声明的组件模板需要其导出类的其他模块。提供者:这个 NgModule 贡献给全球服务集合的服务的创建者;它们在应用程序的所有部分都可以访问。 (您也可以在组件级别指定提供程序,这通常是首选。) bootstrap:主应用程序视图,称为根组件,它托管所有其他应用程序视图。只有根 NgModule 应该设置引导属性。