Что такое entryComponents в angular ngModule?

131

Я работаю над Ionicприложением ( 2.0.0-rc0), которое зависит от angular 2. Итак, новое введение ngModulesвключено. Я добавляю свое app.module.ts.ниже.

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 {}

Что entryComponentsздесь делать? Componentsуже определены в declarations. Так зачем их повторять? Что произойдет, если я не добавлю сюда компонент?

Радж
источник
4
Угловые виды использования entryComponents для того, чтобы «дерево встряхивания» , т.е. только компиляции компонентов, которые фактически используются в проекте вместо компиляции всех компонентов, которые declaredв ngModuleно никогда не используются. angular.io/docs/ts/latest/cookbook/… entrycomponents -
Самар,

Ответы:

155

Это для динамически добавляемых компонентов, которые добавляются с использованием ViewContainerRef.createComponent(). Добавление их в entryComponentsзаставляет автономный компилятор шаблонов скомпилировать их и создать для них фабрики.

Компоненты, зарегистрированные в конфигурациях маршрута, также добавляются автоматически, entryComponentsпоскольку они router-outletтакже используются ViewContainerRef.createComponent()для добавления маршрутизируемых компонентов в DOM.

Автономный компилятор шаблонов (OTC) создает только реально используемые компоненты. Если компоненты не используются напрямую в шаблонах, ОТК не может знать, нужно ли их компилировать. С помощью entryComponents вы можете указать OTC также скомпилировать эти компоненты, чтобы они были доступны во время выполнения.

Что такое входной компонент? (Angular.io)

Документы NgModule (angular.io)

Определяет компоненты, которые также должны быть скомпилированы при определении этого компонента. Для каждого перечисленного здесь компонента Angular создаст ComponentFactory и сохранит его в ComponentFactoryResolver.

Если вы не entryComponentsукажете динамически добавляемый компонент, вы получите сообщение об ошибке в связи с отсутствием фабрики, потому что Angular ее не создал.

См. Также https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html.

Гюнтер Цохбауэр
источник
12
честно говоря, я знаю его на 100% правильный ответ, но для меня он стал вышибалой, не могли бы вы рассказать подробнее?
Панкадж Паркар
26
Трудно сказать, что непонятно. Автономный компилятор шаблонов (OTC) создает только реально используемые компоненты. Если компоненты не используются напрямую в шаблонах, ОТК не может знать, нужно ли их компилировать. С помощью entryComponentsвы можете указать OTC также скомпилировать эти компоненты, чтобы они были доступны во время выполнения.
Günter Zöchbauer
3
stackoverflow.com/questions/36325212/… будет таким примером
Günter Zöchbauer
2
В общем, если компонент указан в declarationsнем, он также должен быть указан entryComponents, верно?
omnomnom
1
только если компонент динамически добавляется createComponentв ваш код или, например, маршрутизатор, который также использует API thod для добавления компонентов.
Günter Zöchbauer
30

Вы не получите объяснения лучше, чем Angular docs: entry-components и ngmodule-faq .

А ниже приведено объяснение из документов angular.

Компонент ввода - это любой компонент, который Angular обязательно загружает по типу.

Компонент, загруженный декларативно через свой селектор, не является входным компонентом.

Большинство компонентов приложения загружаются декларативно. Angular использует селектор компонента для поиска элемента в шаблоне. Затем он создает HTML-представление компонента и вставляет его в DOM в выбранном элементе. Это не входные компоненты.

Некоторые компоненты загружаются только динамически и никогда не упоминаются в шаблоне компонента.

Загрузочный корень AppComponent- это входной компонент. Верно, его селектор соответствует тегу элемента в index.html. Но index.htmlэто не шаблон компонента, и AppComponentселектор не соответствует элементу ни в одном шаблоне компонента.

Angular загружает AppComponent динамически, потому что он либо указан по типу, @NgModule.bootstrapлибо принудительно усилен с помощью метода модуля ngDoBootstrap.

Компоненты в определениях маршрутов также являются входными компонентами. Определение маршрута относится к компоненту по его типу. Маршрутизатор игнорирует селектор маршрутизируемого компонента (если он вообще есть) и динамически загружает компонент в файл RouterOutlet.

Компилятор не может обнаружить эти входные компоненты, ища их в других шаблонах компонентов. Вы должны рассказать о них, добавив их в entryComponentsсписок.

Angular автоматически добавляет в модуль следующие типы компонентов entryComponents:

  • Компонент в @NgModule.bootstrapсписке.
  • Компоненты, указанные в конфигурации маршрутизатора.

Вам не нужно явно упоминать эти компоненты, хотя это безвредно.

Mav55
источник
Прямо сейчас угловые документы недоступны, так что спасибо за это!
Caelum
Похоже, здесь не упоминается, что компоненты в конфигурациях маршрутов автоматически добавляются в entryComponents (так что обычно вам не нужно его определять).
Коннор
1
Если мы создадим компонент, который будет использоваться как объект, EntryComponentдолжны ли мы удалить selectorатрибут? (поскольку он не будет использоваться)
Ронан
24

В других ответах упоминается об этом, но основное резюме:

  • это необходимо, когда компонент НЕ используется внутри шаблона html <my-component />
  • Например, при использовании компонентов диалогового окна Angular Material вы используете компонент косвенно.

Компоненты диалога материалов создаются внутри кода TS, а не в шаблоне:

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

Это требует, чтобы вы зарегистрировали его как entryComponent:

  • entryComponents: [MyExampleDialog]

В противном случае вы получите ошибку:

  • ERROR Error: No component factory found for MyExampleDialog. Did you add it to @NgModule.entryComponents?
Майк Р
источник
2
Лучшее объяснение здесь.
NOP
3

Массив entryComponents используется для определения только компонентов, которых нет в html и которые создаются динамически. Angular требует, чтобы эта подсказка находила входные компоненты и скомпилировала их.

Есть два основных типа входных компонентов:

  • Загрузочный корневой компонент.
  • Компонент, который вы указываете в определении маршрута.

Для получения более подробной информации о компонентах входа, пожалуйста, обратитесь к angular.io https://angular.io/guide/entry-components

Вивек
источник
1

Немного истории о entryComponent

entryComponent- это любой компонент Угловые нагрузки императивно. Вы можете объявить entryComponent, загрузив его NgModuleв определениях маршрутов или в них.

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

В документации говорится ниже

В отличие от этих двух типов компонентов, в шаблон включены декларативные компоненты. Кроме того, есть компоненты, которые вы загружаете в обязательном порядке; то есть входные компоненты.

Теперь, чтобы ответить на ваш конкретный вопрос о entryComponents

В файле есть entryComponentsмассив @NgModule. Вы можете использовать это, чтобы добавить, entryComponentsесли компонент загружается с использованием ViewContainerRef.createComponent().

То есть вы создаете компоненты динамически, а не путем начальной загрузки или в шаблоне.

const componentFactory = this.componentFactoryResolver.resolveComponentFactory(myComp.component);
const viewContainerRef = this.compHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(componentFactory);
Nipuna
источник
0

Начиная с Angular 9 entryComponents , больше не требуется, благодаря тому, что Ivy позволяет исключить эту функцию и поэтому может быть удалена из объявлений модулей.

Устаревшие API и функции - entryComponentsи ANALYZE_FOR_ENTRY_COMPONENTSбольше не требуемые

Ранее entryComponentsмассив в NgModuleопределении использовался, чтобы сообщить компилятору, какие компоненты будут созданы и вставлены динамически. С Ivy это больше не является требованием, и entryComponentsмассив можно удалить из существующих объявлений модулей. То же самое и с ANALYZE_FOR_ENTRY_COMPONENTSтокеном инъекции.

Угловой плющ

Ivy - это кодовое название конвейера компиляции и рендеринга Angular следующего поколения. В выпуске Angular версии 9 новые инструкции компилятора и среды выполнения используются по умолчанию вместо старых компилятора и среды выполнения, известных как View Engine.

ясень
источник