Що таке вхідні компоненти в кутовому ngмодулі?


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) створює лише компоненти, які фактично використовуються. Якщо компоненти не використовуються безпосередньо в шаблонах, 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% правильну відповідь, але вийшов для мене відмовою, ви можете, будь ласка, детальніше розглянути?
Pankaj Parkar

26
Важко сказати, що незрозуміло. Офлайн-компілятор шаблонів (OTC) створює лише компоненти, які фактично використовуються. Якщо компоненти не використовуються безпосередньо в шаблонах, OTC не може знати, чи потрібно їх компілювати. З entryComponentsвами можуть сказати OTC також скомпілювати ці компоненти , щоб вони доступні під час виконання.
Günter Zöchbauer

3
stackoverflow.com/questions/36325212/… був би таким прикладом
Günter Zöchbauer

2
Так загалом, якщо компонент вказаний у declarationsньому, він також повинен бути вказаний у entryComponents, правда?
omnomnom

1
лише якщо компонент динамічно додається createComponentу ваш код або, наприклад, маршрутизатор, який також використовує thod API для додавання компонентів.
Günter Zöchbauer

30

Ви не отримаєте пояснення краще, ніж Angular docs: entry-компоненти та ngmodule-faq .

А нижче пояснення з кутових документів.

Вхідний компонент - це будь-який компонент, який кутовий завантажується обов'язково за типом.

Компонент, завантажений декларативно через свій селектор, не є вхідним компонентом.

Більшість компонентів програми завантажуються декларативно. Angular використовує селектор компонента, щоб знайти елемент у шаблоні. Потім він створює HTML-представлення компонента і вставляє його в DOM у вибраному елементі. Це не вхідні компоненти.

Кілька компонентів завантажуються лише динамічно і ніколи не посилаються на шаблон компонента.

Корінь завантаженого завантаження AppComponentє вхідним компонентом. Правда, його селектор відповідає тегу елементів у index.html. Але index.htmlце не шаблон компонента, і AppComponentселектор не відповідає елементу в будь-якому компонентному шаблоні.

Кутове завантаження AppComponent динамічно, оскільки воно або перераховане за типом, @NgModule.bootstrapабо обов'язково завантажується методом ngDoBootstrap модуля.

Компоненти у визначеннях маршрутів також є компонентами введення. Визначення маршруту відноситься до компонента за його типом. Маршрутизатор ігнорує селектор маршрутизованого компонента (якщо у нього навіть є) і динамічно завантажує компонент у RouterOutlet.

Компілятор не може виявити ці вхідні компоненти, шукаючи їх в інших шаблонах компонентів. Ви повинні розповісти про них, додавши їх до entryComponentsсписку.

Angular автоматично додає до модуля такі типи компонентів entryComponents:

  • Компонент у @NgModule.bootstrapсписку.
  • Компоненти, на які посилається в конфігурації маршрутизатора.

Не потрібно чітко згадувати про ці компоненти, хоча робити це нешкідливо.


Зараз кутові документи недоступні, тому дякую ТАК за це!
Caelum

Це, мабуть, не згадує, що компоненти в конфігураціях маршрутів автоматично додаються до entryComponents (тому зазвичай ніколи не потрібно визначати це).
Коннор

Якщо ми створимо компонент , який буде використовуватися як EntryComponentми повинні видалити selectorатрибут? (оскільки він не буде використаний)
Ronan

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.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);

0

Станом на Angular 9 entryComponents більше не потрібно завдяки Ivy, що дозволяє цю функцію застаріти, а тому може бути видалений з декларацій модулів.

Застарілі API - інтерфейси і можливості - entryComponentsі ANALYZE_FOR_ENTRY_COMPONENTSбільше не потрібно

Раніше entryComponentsмасив у NgModuleвизначенні використовувався для того, щоб повідомити компілятору, які компоненти будуть створені та вставлені динамічно. Для Ivy це вже не вимога, і entryComponentsмасив можна видалити з існуючих декларацій модуля. Те саме стосується і ANALYZE_FOR_ENTRY_COMPONENTSмаркера для ін'єкцій.

Кутовий плющ

Ivy - це кодове ім'я для компіляції та рендерингу нового покоління Angular. З версією 9 випуску Angular, нові інструкції щодо компілятора та режиму виконання використовуються за замовчуванням замість старих компіляторів і часу виконання, відомих як View Engine.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.