¿Cuál es la diferencia entre declaraciones, proveedores e importación en NgModule?

Respuestas:

517

Conceptos angulares

  • imports hace que las declaraciones exportadas de otros módulos estén disponibles en el módulo actual
  • declarationsdeben hacer que las directivas (incluidos los componentes y las tuberías) del módulo actual estén disponibles para otras directivas en el módulo actual. Los selectores de directivas, componentes o tuberías solo se comparan con el HTML si se declaran o importan.
  • providersson para hacer que los servicios y valores sean conocidos por DI (inyección de dependencia). Se agregan al ámbito raíz y se inyectan a otros servicios o directivas que los tienen como dependencia.

Un caso especial providersson los módulos con carga lenta que obtienen su propio inyector secundario. providersde un módulo con carga diferida solo se proporcionan a este módulo con carga diferida de forma predeterminada (no toda la aplicación como lo es con otros módulos).

Para obtener más detalles sobre los módulos, consulte también https://angular.io/docs/ts/latest/guide/ngmodule.html

  • exportshace que los componentes, directivas y tuberías estén disponibles en módulos a los que se agrega este módulo imports. exportstambién se puede usar para reexportar módulos como CommonModule y FormsModule, que a menudo se realiza en módulos compartidos.

  • entryComponentsregistra componentes para la compilación fuera de línea para que puedan usarse con ViewContainerRef.createComponent(). Los componentes utilizados en las configuraciones de enrutador se agregan implícitamente.

Importaciones TypeScript (ES2015)

import ... from 'foo/bar'(que puede resolverse en unindex.ts ) son para importaciones de TypeScript. Los necesita cada vez que utiliza un identificador en un archivo de mecanografía que se declara en otro archivo de mecanografía.

Angular @NgModule() importsy TypeScript importson conceptos completamente diferentes .

Consulte también jDriven: sintaxis de importación de TypeScript y ES6

La mayoría de ellos son en realidad sintaxis de módulo ECMAScript 2015 (ES6) que TypeScript también usa.

Günter Zöchbauer
fuente
1
Creo, pero no estoy seguro, que la última recomendación es colocar proveedores de toda la aplicación en un CoreModule, en lugar de usarlos forRoot()en un módulo con carga lenta. ¿Estás de acuerdo? Ver El Módulo Central . El enlace a # shared-module-for-root ya no existe.
Mark Rajcok
1
Excelente explicación Gracias, @ günter-zöchbauer. La única mención es que afaik importes una funcionalidad JS (ES2015), no TypeScript. :)
cassi.lup
y lo que es exportar [] en NgModule apesta como exportación: [MatCheckBox]
Omar Isaid
44
Para ser honesto, creo que el diseño de NgModule of Angular es torpe y oscuro en comparación con Vue y React . Necesita importar otro módulo con imports, pero exportar sus declarables (componente, directiva, canalización) con exports. Entonces, los objetivos principales de importsy exportsson cosas diferentes. En cambio, el objetivo principal de exportses tu declarations. Declaras tu componente por declarations, pero para el componente dinámico cargado, necesitas ponerlo entryComponents. Mientras tanto, providersDI las gestiona en otra historia.
xuemind
2
una respuesta complicada que describe un marco complicado
Donato
85

imports se utilizan para importar módulos de soporte como FormsModule, RouterModule, CommonModule o cualquier otro módulo de características personalizado.

declarationsse utilizan para declarar componentes, directivas, tuberías que pertenecen al módulo actual. Todos los que están dentro de las declaraciones se conocen. Por ejemplo, si tenemos un componente, digamos UsernameComponent, que muestra una lista de los nombres de usuario y también tenemos una tubería, digamos toupperPipe, que transforma una cadena en una cadena de letras mayúsculas. Ahora, si queremos mostrar los nombres de usuario en letras mayúsculas en nuestro UsernameComponent, entonces podemos usar el toupperPipe que habíamos creado antes, pero la pregunta es cómo UsernameComponent sabe que existe el toupperPipe y cómo puede acceder y usarlo. Aquí vienen las declaraciones, podemos declarar UsernameComponent y toupperPipe.

Providers se utilizan para inyectar los servicios requeridos por componentes, directivas, tuberías en el módulo.

Padrino
fuente
3
"declaraciones: se utiliza para declarar componentes, directivas, tuberías que pertenecen al módulo actual. Todo dentro de las declaraciones se conoce entre sí". esta debería ser la respuesta aceptada
Deen John
60

Los componentes se declaran, los módulos se importan y se proporcionan servicios. Un ejemplo con el que estoy trabajando:

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 { }
SanSolo
fuente
3
Me gusta la simplicidad de esta explicación, pero me hace preguntarme por qué no hay una sola propiedad "stuffsThisComponentNeeds". Parece que todos están lidiando con lo mismo, lo que está haciendo que otras partes del código estén disponibles para el componente actual.
redOctober13
1
@ redOctober13 Estoy de acuerdo. En Node.js, por ejemplo, todo se importa de la misma manera, independientemente de si se trata de un modelo de DB, módulo, servicio o paquete de terceros instalado. Y creo que lo mismo sucede con reactJS
SanSolo
18

@NgModuleConstrucciones angulares :

  1. import { x } from 'y';: Esta es la sintaxis de tipografía estándar (sintaxis de ES2015/ES6módulo) para importar código de otros archivos. Esto no es angular específico . Además, técnicamente esto no forma parte del módulo, solo es necesario obtener el código necesario dentro del alcance de este archivo.
  2. imports: [FormsModule]: Importas otros módulos aquí. Por ejemplo, importamos FormsModuleen el siguiente ejemplo. Ahora podemos usar la funcionalidad que FormsModule tiene para ofrecer en este módulo.
  3. declarations: [OnlineHeaderComponent, ReCaptcha2Directive]: Pones aquí tus componentes, directivas y tuberías. Una vez declarado aquí, ahora puede usarlos en todo el módulo. Por ejemplo, ahora podemos usar OnlineHeaderComponenten la AppComponentvista (archivo html). Angular sabe dónde encontrar esto OnlineHeaderComponentporque está declarado en el @NgModule.
  4. providers: [RegisterService]: Aquí se definen nuestros servicios de este módulo específico. Puede usar los servicios en sus componentes inyectando inyección de dependencia.

Módulo de ejemplo:

// 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 { }
Willem van der Veen
fuente
10

Agregar una hoja de trucos rápida que puede ayudar después del largo descanso con Angular:


Declaraciones

Ejemplo:

declarations: [AppComponent]

¿Qué podemos inyectar aquí? Componentes, tuberías, directivas.


IMPORTACIONES

Ejemplo:

imports: [BrowserModule, AppRoutingModule]

¿Qué podemos inyectar aquí? otros módulos


PROVEEDORES

Ejemplo:

providers: [UserService]

¿Qué podemos inyectar aquí? servicios


OREJA

Ejemplo:

bootstrap: [AppComponent]

¿Qué podemos inyectar aquí? El componente principal que generará este módulo (nodo principal superior para un árbol de componentes)


COMPONENTES DE ENTRADA

Ejemplo:

entryComponents: [PopupComponent]

¿Qué podemos inyectar aquí? componentes generados dinámicamente (por ejemplo, usando ViewContainerRef.createComponent ())


EXPORTAR

Ejemplo:

export: [TextDirective, PopupComponent, BrowserModule]

¿Qué podemos inyectar aquí? componentes, directivas, módulos o tuberías a los que nos gustaría tener acceso en otro módulo (después de importar este módulo)

Przemek Struciński
fuente
1
¿Qué pasa con la exportación?
lugte098
@ lugte098 He agregado la exportación a esta lista
Przemek Struciński, el
Me encanta este diseño para la explicación, muy digerible. ¡Gracias!
Aaron Jordan
1
  1. declaraciones : Esta propiedad informa sobre los componentes, directivas y tuberías que pertenecen a este módulo.
  2. exportaciones : el subconjunto de declaraciones que deben ser visibles y utilizables en las plantillas de componentes de otros NgModules.
  3. importaciones : otros módulos cuyas clases exportadas son necesarias para las plantillas de componentes declaradas en este NgModule.
  4. proveedores : creadores de servicios que este NgModule contribuye a la colección global de servicios; se vuelven accesibles en todas las partes de la aplicación. (También puede especificar proveedores en el nivel de componente, que a menudo se prefiere).
  5. bootstrap : la vista principal de la aplicación, denominada componente raíz, que aloja todas las demás vistas de la aplicación. Solo el NgModule raíz debe establecer la propiedad bootstrap.
Yogesh Waghmare
fuente