angular ngModule中的entryComponents是什么?


131

我正在开发依赖的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 {}

entryComponents在这里做什么?Components已在中定义declarations。那么有什么需要重复的?如果我在此处不包含组件会怎样?


4
角用途entryComponents,使“树摇晃”,即只有在编译实际项目中使用编译所有那些组件,而不是组件declaredngModule但从未使用过。angular.io/docs/ts/latest/cookbook/... entrycomponents -
萨马

Answers:


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也可以编译此组件,以便它们在运行时可用。
君特Zöchbauer


2
因此,通常来说,如果在declarations其中列出了组件,也应该在中列出entryComponents,对吗?
omn​​omnom '16

1
仅当createComponent在您的代码中动态添加了组件时,或者例如也使用thod API添加组件的路由器。
君特Zöchbauer

30

您不会比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列表中的组件。
  • 路由器配置中引用的组件。

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


目前,尚无角度文档,因此非常感谢!
Caelum '18

这似乎没有提到路由配置中的组件会自动添加到entryComponents中(因此您通常不需要定义它)。
康纳

如果我们创建一个组件用作,EntryComponent我们应该删除该selector属性吗?(因为它不会被使用)
Ronan

24

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

  • 在html模板中未使用组件时需要它 <my-component />
  • 例如,当使用“角度材质”对话框组件时,可以间接使用组件。

材质对话框组件是在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);

0

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

过时的API和功能- entryComponentsANALYZE_FOR_ENTRY_COMPONENTS不再需要

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

角常春藤

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.