O que é entryComponents no ngModule angular?


131

Estou trabalhando em um Ionicaplicativo ( 2.0.0-rc0) do qual depende angular 2. Portanto, a nova introdução de ngModulesestá incluída. Estou adicionando o meu app.module.ts.abaixo.

import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { Users } from '../pages/users/users';

@NgModule({
  declarations: [
    MyApp,
    Users
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    Users
  ]
})
export class AppModule {}

O que entryComponentsfaz aqui? Componentsjá estão definidos em declarations. Então, qual é a necessidade de repeti-los? O que aconteceria se eu não incluísse um componente aqui?


4
Angular usa entryComponents para ativar a "trepidação de árvore", ou seja, apenas compilar os componentes que são realmente usados ​​no projeto em vez de compilar todos os componentes que estão declareddentro, ngModulemas nunca são usados. angular.io/docs/ts/latest/cookbook/… entrycomponents -
— Samar

Respostas:


155

Isto é para componentes adicionados dinamicamente que são adicionados usando ViewContainerRef.createComponent(). Adicioná-los a entryComponentsinforma ao compilador de modelos offline para compilá-los e criar fábricas para eles.

Os componentes registrados nas configurações de rota também são adicionados automaticamente entryComponentsporque router-outlettambém são usados ViewContainerRef.createComponent()para adicionar componentes roteados ao DOM.

O compilador de modelos offline (OTC) cria apenas componentes que são realmente usados. Se os componentes não forem usados ​​diretamente nos modelos, o OTC não saberá se eles precisam ser compilados. Com entryComponents, você pode solicitar ao OTC que também compile esses componentes para que estejam disponíveis em tempo de execução.

O que é um componente de entrada? (angular.io)

Documentos do NgModule (angular.io)

Define os componentes que devem ser compilados também quando esse componente é definido. Para cada componente listado aqui, o Angular criará um ComponentFactory e o armazenará no ComponentFactoryResolver.

Se você não listar um componente adicionado dinamicamente, entryComponentsreceberá uma mensagem de erro sobre uma fábrica ausente porque o Angular não terá criado um.

Veja também https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html


12
falando francamente, eu sei sua resposta 100% correta, mas fui bouncer para mim, você poderia, por favor, elaborar mais?
— Pankaj Parkar 28/09/16

26
Difícil dizer o que não está claro. O compilador de modelos offline (OTC) cria apenas componentes que são realmente usados. Se os componentes não forem usados ​​diretamente nos modelos, o OTC não saberá se eles precisam ser compilados. Com entryComponentsvocê, você pode dizer ao OTC para compilar esses componentes para que estejam disponíveis em tempo de execução.
— Günter Zöchbauer 28/09


2
Então, em geral, se o componente estiver listado, declarationsele também deve estar listado entryComponents, certo?
— Omnomnom 13/12

1
somente se um componente for adicionado dinamicamente createComponentno seu código ou, por exemplo, o roteador que também usa a API thod para adicionar componentes.
— Günter Zöchbauer

30

Você não terá uma explicação melhor do que os documentos angulares: entry-components e ngmodule-faq .

E abaixo está a explicação dos documentos angulares.

Um componente de entrada é qualquer componente que o Angular carregue imperativamente por tipo.

Um componente carregado declarativamente por meio de seu seletor não é um componente de entrada.

A maioria dos componentes do aplicativo é carregada declarativamente. Angular usa o seletor do componente para localizar o elemento no modelo. Em seguida, ele cria a representação HTML do componente e a insere no DOM no elemento selecionado. Estes não são componentes de entrada.

Alguns componentes são carregados apenas dinamicamente e nunca são referenciados em um modelo de componente.

A raiz de inicialização AppComponenté um componente de entrada. Verdadeiro, seu seletor corresponde a uma tag de elemento em index.html. Mas index.htmlnão é um modelo de componente e o AppComponentseletor não corresponde a um elemento em nenhum modelo de componente.

O Angular carrega o AppComponent dinamicamente porque é listado por tipo @NgModule.bootstrapou inicializado imperativamente com o método ngDoBootstrap do módulo.

Os componentes nas definições de rota também são componentes de entrada. Uma definição de rota refere-se a um componente por seu tipo. O roteador ignora o seletor de um componente roteado (se houver um) e carrega o componente dinamicamente em umRouterOutlet .

O compilador não pode descobrir esses componentes de entrada procurando-os em outros modelos de componentes. Você deve contar sobre eles adicionando-os à entryComponentslista.

O Angular adiciona automaticamente os seguintes tipos de componentes aos módulos entryComponents:

  • O componente na @NgModule.bootstraplista.
  • Componentes mencionados na configuração do roteador.

Você não precisa mencionar esses componentes explicitamente, embora isso seja inofensivo.


No momento, os documentos angulares não estão disponíveis, então agradeça SO por isso!
— Caelum

Isso não parece mencionar que os componentes nas configurações de rota são adicionados automaticamente ao entryComponents (portanto, você nunca precisa defini-lo).
— Connor

Se criarmos um componente para ser usado como EntryComponentdevemos remover o selectoratributo? (uma vez que não serão utilizados)
— Ronan

24

As outras respostas mencionam isso, mas o resumo básico é:

  • é necessário quando um componente NÃO é usado dentro de um modelo html <my-component />
  • Por exemplo, ao usar os componentes da caixa de diálogo Material angular, você o usa indiretamente.

Os componentes de diálogo de materiais são criados dentro do código TS e não no modelo:

    const dialogRef = this.dialog.open(MyExampleDialog, { width: '250px' });
  }

Isso exige que você o registre como um entryComponent:

  • entryComponents: [MyExampleDialog]

Caso contrário, você receberá um erro:

  • ERROR Error: No component factory found for MyExampleDialog. Did you add it to @NgModule.entryComponents?

2
A melhor explicação aqui.
— nop

3

A matriz entryComponents é usada para definir apenas componentes que não são encontrados no html e criados dinamicamente. Angular requer esta dica para encontrar o componente de entrada e compilá-lo.

Existem dois tipos principais de componentes de entrada:

  • O componente raiz inicializado.
  • Um componente que você especifica em uma definição de rota.

Para obter informações mais detalhadas sobre os componentes de entrada, consulte angular.io https://angular.io/guide/entry-components


1

Um pouco de fundo sobre entryComponent

entryComponenté qualquer componente Cargas angulares imperativamente. Você pode declarar entryComponentinicializando-o nas NgModuleou nas definições de rota.

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent] // bootstrapped entry component
})

A documentação diz abaixo

Para contrastar os dois tipos de componentes, existem componentes incluídos no modelo, que são declarativos. Além disso, existem componentes que você carrega imperativamente; isto é, componentes de entrada.

Agora, para responder sua pergunta específica sobre entryComponents

Há entryComponentsmatriz no @NgModulearquivo. Você pode usar isso para adicionar entryComponentsse o componente é inicializado usando ViewContainerRef.createComponent().

Ou seja, você está criando componentes dinamicamente e não através da inicialização ou no modelo.

const componentFactory = this.componentFactoryResolver.resolveComponentFactory(myComp.component);
const viewContainerRef = this.compHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(componentFactory);

0

O Angular 9 entryComponents não é mais necessário, graças ao Ivy, que permite que esse recurso seja descontinuado e, portanto, pode ser removido das declarações do módulo.

APIs e recursos obsoletos - entryComponentse ANALYZE_FOR_ENTRY_COMPONENTSnão são mais necessários

Anteriormente, a entryComponentsmatriz na NgModuledefinição era usada para informar ao compilador quais componentes seriam criados e inseridos dinamicamente. Com o Ivy, isso não é mais um requisito e a entryComponentsmatriz pode ser removida das declarações de módulos existentes. O mesmo se aplica ao ANALYZE_FOR_ENTRY_COMPONENTStoken de injeção.

Hera angular

Ivy é o nome de código para o pipeline de compilação e renderização de próxima geração da Angular. Com o lançamento da versão 9 do Angular, as novas instruções do compilador e do tempo de execução são usadas por padrão em vez do compilador e do tempo de execução mais antigos, conhecido como View Engine.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.