155

我正在开发一个Ionic依赖2.0.0-rc0angular 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 {}

在这里做什么entryComponentsComponents已经定义在declarations. 那么重复它们有什么必要呢?如果我在这里不包含组件会发生什么?

4

7 回答 7

173

这适用于使用ViewContainerRef.createComponent(). 添加它们entryComponents告诉离线模板编译器编译它们并为它们创建工厂。

路由配置中注册的组件也会自动添加到entryComponents,因为router-outlet也用于ViewContainerRef.createComponent()将路由组件添加到 DOM。

离线模板编译器 (OTC) 仅构建实际使用的组件。如果组件没有直接在模板中使用,OTC 就无法知道它们是否需要编译。使用 entryComponents,您可以告诉 OTC 也编译这些组件,以便它们在运行时可用。

什么是入口组件?(角度.io)

NgModule 文档 (angular.io)

定义在定义此组件时也应编译的组件。对于此处列出的每个组件,Angular 将创建一个 ComponentFactory 并将其存储在 ComponentFactoryResolver 中。

如果你没有列出动态添加的组件,entryComponents你会收到一条关于缺少工厂的错误消息,因为 Angular 不会创建一个。

另请参阅https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html

于 2016-09-28T19:37:42.497 回答
42

其他答案提到了这一点,但基本总结是:

  • 在html中不使用组件时需要它,例如:<my-component />
  • 例如,使用 Angular Material Dialogs 您可以间接使用它们,它们是在TS 代码而不是 html 中创建的:
openDialog() {
    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?
于 2019-01-03T15:30:23.297 回答
33

你不会得到比 Angular 文档更好的解释:entry-componentsngmodule-faq

以下是角度文档的解释。

入口组件是 Angular 按类型强制加载的任何组件。

通过其选择器以声明方式加载的组件不是入口组件。

大多数应用程序组件都是以声明方式加载的。Angular 使用组件的选择器来定位模板中的元素。然后它创建组件的 HTML 表示并将其插入到 DOM 中的选定元素处。这些不是入口组件。

少数组件仅动态加载,从不在组件模板中引用。

自举根AppComponent是一个入口组件。没错,它的选择器匹配 index.html 中的元素标签。但是index.html不是组件模板,并且AppComponent选择器不匹配任何组件模板中的元素。

Angular 动态加载 AppComponent,因为它要么按类型列出,要么@NgModule.bootstrap使用模块的 ngDoBootstrap 方法强制地进行引导。

路由定义中的组件也是入口组件。路由定义通过其类型引用组件。路由器会忽略路由组件的选择器(如果它甚至有选择器)并将组件动态加载到RouterOutlet.

编译器无法通过在其他组件模板中查找这些入口组件来发现它们。entryComponents您必须通过将它们添加到列表中来告诉它们。

Angular 会自动将以下类型的组件添加到模块的entryComponents:

  • 列表中的组件@NgModule.bootstrap
  • 路由器配置中引用的组件。

您不必明确提及这些组件,尽管这样做是无害的。

于 2017-03-08T19:01:26.910 回答
7

由于Ivy 允许弃用此功能,因此不再需要Angular 9 ,因此可以从模块声明中删除。 entryComponents

已弃用的 API 和功能 -entryComponents不再ANALYZE_FOR_ENTRY_COMPONENTS需要

以前,定义中的entryComponents数组NgModule用于告诉编译器将动态创建和插入哪些组件。使用 Ivy,这不再是必需的,并且entryComponents可以从现有模块声明中删除数组。这同样适用于ANALYZE_FOR_ENTRY_COMPONENTS注入令牌。

角常春藤

Ivy 是 Angular 下一代编译和渲染管道的代号。在 Angular 9 版本中,默认使用新的编译器和运行时指令,而不是旧的编译器和运行时指令,即 View Engine。

于 2020-07-17T03:22:35.207 回答
5

entryComponents 数组用于仅定义在 html 中找不到并动态创建的组件。Angular 需要这个提示来查找入口组件并编译它们。

入口组件有两种主要类型:

  • 引导的根组件。
  • 您在路由定义中指定的组件。

有关入口组件的更多详细信息,请参阅 angular.io https://angular.io/guide/entry-components

于 2019-01-03T16:00:21.457 回答
2

在 Angular 13.1 中,不推荐使用 EntryComponent。参考:https ://github.com/angular/angular/blob/master/CHANGELOG.md#1310-2021-12-09

另请参阅:https ://angular.io/guide/deprecations#entrycomponents-and-analyze_for_entry_components-no-longer-required

于 2021-12-17T06:16:52.020 回答
1

一点背景知识entryComponent

entryComponent是任何组件 Angular 强制加载。您可以通过在路由定义中或路由定义中entryComponent引导它来声明。NgModule

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

文档如下

为了对比这两种类型的组件,模板中包含了一些组件,它们是声明性的。此外,您还可以强制加载一些组件;也就是入口组件。

现在回答你的具体问题entryComponents

文件中有entryComponents数组@NgModuleentryComponents如果组件是使用引导的,您可以使用它来添加ViewContainerRef.createComponent()

那就是您正在动态创建组件,而不是通过引导或在模板中创建。

const componentFactory = this.componentFactoryResolver.resolveComponentFactory(myComp.component);
const viewContainerRef = this.compHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(componentFactory);
于 2019-08-06T04:26:27.210 回答