Qual é a diferença entre declarações, provedores e importação no NgModule?

388

Estou tentando entender Angular (às vezes chamado Angular2 +), e me deparei com @Module:

  1. Importações

  2. Declarações

  3. Fornecedores

Após o início rápido angular

Ramesh Papaganti
fonte

Respostas:

517

Conceitos angulares

  • imports disponibiliza as declarações exportadas de outros módulos no módulo atual
  • declarationsdevem disponibilizar diretivas (incluindo componentes e tubos) do módulo atual para outras diretivas no módulo atual. Os seletores de diretivas, componentes ou tubulações são compatíveis apenas com o HTML se forem declarados ou importados.
  • providersdevem tornar os serviços e valores conhecidos pelo DI (injeção de dependência). Eles são adicionados ao escopo raiz e são injetados em outros serviços ou diretivas que os possuem como dependência.

Um caso especial providerssão os módulos carregados preguiçosamente que recebem seu próprio injetor infantil. providersde um módulo carregado lento são fornecidos somente a este módulo carregado lento por padrão (não o aplicativo inteiro como em outros módulos).

Para mais detalhes sobre os módulos, consulte também https://angular.io/docs/ts/latest/guide/ngmodule.html

  • exportsdisponibiliza os componentes, diretrizes e tubulações nos módulos aos quais esse módulo é adicionado imports. exportstambém pode ser usado para reexportar módulos como CommonModule e FormsModule, que geralmente é feito em módulos compartilhados.

  • entryComponentsregistra componentes para compilação offline para que eles possam ser usados ViewContainerRef.createComponent(). Os componentes usados ​​nas configurações do roteador são adicionados implicitamente.

Importações TypeScript (ES2015)

import ... from 'foo/bar'(que pode resolver para umindex.ts ) são para importações TypeScript. Você precisa delas sempre que usar um identificador em um arquivo datilografado declarado em outro arquivo datilografado.

Angular @NgModule() importse TypeScript importsão conceitos totalmente diferentes .

Consulte também jDriven - sintaxe de importação TypeScript e ES6

A maioria deles é na verdade simples sintaxe do módulo ECMAScript 2015 (ES6) que o TypeScript também usa.

Günter Zöchbauer
fonte
11
Eu acho, mas não tenho certeza, que a recomendação mais recente é colocar provedores de todo o aplicativo em um CoreModule, em vez de usar forRoot()em um módulo carregado preguiçosamente. Você concorda? Consulte O módulo principal . O link para # shared-module-for-root não existe mais.
Mark Rajcok
11
Excelente explicação. Obrigado, @ günter-zöchbauer. A única menção é que o afaik importé uma funcionalidade JS (ES2015), não uma TypeScript. :)
cassi.lup
e o que é exportar [] no NgModule é péssimo como exportar: [MatCheckBox]
Omar Isaid
4
Para ser sincero, acho que o design do NgModule of Angular é desajeitado e obscuro em comparação com o Vue e o React . Você precisa importar outro módulo com imports, mas exportar seus declaráveis ​​(componente, diretiva, canal) com exports. Então, os principais alvos importse exportssão coisas diferentes. Em vez disso, o principal objetivo exportsé o seu declarations. Você declara seu componente por declarations, mas para o componente carregado dinâmico, é necessário inseri-lo entryComponents. Enquanto isso, eles providerssão gerenciados em outra história pela DI.
xuemind
11
uma resposta complicada descrevendo uma estrutura complicada
Donato
85

imports são usados ​​para importar módulos de suporte, como FormsModule, RouterModule, CommonModule ou qualquer outro módulo de recurso personalizado.

declarationssão usados ​​para declarar componentes, diretivas, tubulações que pertencem ao módulo atual. Todos dentro das declarações se conhecem. Por exemplo, se tivermos um componente, digamos UsernameComponent, que exibe uma lista dos nomes de usuário e também temos um canal, digamos toupperPipe, que transforma uma string em uma letra maiúscula. Agora, se queremos mostrar nomes de usuário em letras maiúsculas em nosso UsernameComponent, podemos usar o toupperPipe que criamos anteriormente, mas a questão é como o UsernameComponent sabe que o toupperPipe existe e como ele pode acessá-lo e usá-lo. Aí vêm as declarações, podemos declarar UsernameComponent e toupperPipe.

Providers são usados ​​para injetar os serviços exigidos por componentes, diretivas, tubulações no módulo.

Padrinho
fonte
3
"declarações: é usado para declarar componentes, diretivas, canais que pertencem ao módulo atual. Tudo dentro das declarações se conhecem." esta deve ser a resposta aceita
Deen John
60

Os componentes são declarados, os módulos são importados e os serviços são fornecidos. Um exemplo com o qual estou trabalhando:

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
fonte
3
Gosto da simplicidade dessa explicação, mas me pergunto por que não existe apenas uma propriedade "stuffsThisComponentNeeds"? Parece que todos estão lidando com a mesma coisa, que está disponibilizando outros trechos de código para o componente atual.
redOctober13
11
@ redOctober13 Eu concordo. No Node.js, por exemplo, tudo é importado da mesma maneira, independentemente de ser um modelo de banco de dados, módulo, serviço ou pacote de terceiros instalado. E eu acho que mesmo acontece com reactJS
Sansolo
18

@NgModuleConstruções angulares :

  1. import { x } from 'y';: Esta é a sintaxe padrão de texto datilografado ( ES2015/ES6sintaxe do módulo) para importar código de outros arquivos. Isto não é específico angular . Além disso, tecnicamente, isso não faz parte do módulo, é apenas necessário obter o código necessário dentro do escopo deste arquivo.
  2. imports: [FormsModule]: Você importa outros módulos aqui. Por exemplo, importamos FormsModuleno exemplo abaixo. Agora podemos usar a funcionalidade que o FormsModule tem a oferecer ao longo deste módulo.
  3. declarations: [OnlineHeaderComponent, ReCaptcha2Directive]: Você coloca seus componentes, diretrizes e tubos aqui. Uma vez declarado aqui, agora você pode usá-los em todo o módulo. Por exemplo, agora podemos usar o OnlineHeaderComponentna AppComponentvisualização (arquivo html). Angular sabe onde encontrar isso OnlineHeaderComponentporque é declarado no @NgModule.
  4. providers: [RegisterService]: Aqui nossos serviços deste módulo específico são definidos. Você pode usar os serviços em seus componentes injetando injeção de dependência.

Módulo de exemplo:

// 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
fonte
10

Adicionando uma folha de dicas rápidas que pode ajudar após o longo intervalo com o Angular:


DECLARAÇÕES

Exemplo:

declarations: [AppComponent]

O que podemos injetar aqui? Componentes, tubos, diretivas


IMPORTAÇÕES

Exemplo:

imports: [BrowserModule, AppRoutingModule]

O que podemos injetar aqui? outros módulos


FORNECEDORES

Exemplo:

providers: [UserService]

O que podemos injetar aqui? Serviços


BOOTSTRAP

Exemplo:

bootstrap: [AppComponent]

O que podemos injetar aqui? o componente principal que será gerado por este módulo (nó pai principal de uma árvore de componentes)


COMPONENTES DE INSCRIÇÃO

Exemplo:

entryComponents: [PopupComponent]

O que podemos injetar aqui? componentes gerados dinamicamente (por exemplo, usando ViewContainerRef.createComponent ())


EXPORTAÇÃO

Exemplo:

export: [TextDirective, PopupComponent, BrowserModule]

O que podemos injetar aqui? componentes, diretrizes, módulos ou tubulações que gostaríamos de ter acesso a eles em outro módulo (após a importação deste módulo)

Przemek Struciński
fonte
11
E a exportação?
Lugte098 10/09/19
@ lugte098 Adicionei exportar a esta lista
Przemek Struciński
Eu amo esse layout para a explicação, muito digerível. Obrigado!
Aaron Jordan
1
  1. declarações : Esta propriedade informa sobre os componentes, diretivas e tubulações que pertencem a este módulo.
  2. Exportações : o subconjunto de declarações que devem estar visíveis e utilizáveis ​​nos modelos de componentes de outros NgModules.
  3. importações : outros módulos cujas classes exportadas são necessárias pelos modelos de componentes declarados neste NgModule.
  4. provedores : criadores de serviços com os quais este NgModule contribui para a coleção global de serviços; eles se tornam acessíveis em todas as partes do aplicativo. (Você também pode especificar provedores no nível do componente, o que geralmente é preferido.)
  5. bootstrap : a visualização principal do aplicativo, chamada componente raiz, que hospeda todas as outras visualizações do aplicativo. Somente o NgModule raiz deve definir a propriedade de autoinicialização.
yogesh waghmare
fonte