什么是角度ngModule中的entryComponents?

时间:2016-09-28 19:35:03

标签: angular ionic-framework ionic2

我正在开发一个取决于Ionic的{​​{1}}应用(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。那么重复它们的必要性是什么?如果我在这里不包含组件会怎么样?

6 个答案:

答案 0 :(得分:117)

这适用于使用ViewContainerRef.createComponent()添加的动态添加组件。将它们添加到entryComponents会告诉离线模板编译器编译它们并为它们创建工厂。

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

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

What is an entry component? (angular.io)

NgModule docs (angular.io)

  

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

如果您没有向entryComponents列出动态添加的组件,则会收到错误消息,因为Angular不会创建一个。

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

答案 1 :(得分:25)

你不会比Angular docs更好地获得解释。

以下是角度文档的解释。

  

条目组件是Angular按类型强制加载的任何组件。

     

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

     

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

     

一些组件仅动态加载,并且永远不会在组件模板中引用。

     

引导根AppComponent是一个条目组件。是的,它的选择器匹配index.html中的元素标记。但index.html不是组件模板,AppComponent选择器与任何组件模板中的元素都不匹配。

     

Angular动态加载AppComponent,因为它按@NgModule.bootstrap中的类型列出,或者使用模块的ngDoBootstrap方法强制提升。

     

路由定义中的组件也是条目组件。路由定义是指按类型划分的组件。路由器忽略路由组件的选择器(如果它只有一个)并将组件动态加载到RouterOutlet

     

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

     

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

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

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

答案 2 :(得分:2)

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

  • 在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?

答案 3 :(得分:2)

自Angular版本以来, 9 entryComponents不再需要,因为Ivy允许弃用该功能,因此可以从模块声明中删除。

Deprecated APIs and features - entryComponents and ANALYZE_FOR_ENTRY_COMPONENTS no longer required

以前,entryComponents定义中的NgModule数组用于告诉编译器将动态创建和插入哪些组件。使用Ivy,就不再需要了,可以从现有模块声明中删除entryComponents数组。 ANALYZE_FOR_ENTRY_COMPONENTS注入令牌也是如此。

Angular Ivy

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

答案 4 :(得分:1)

关于entryComponent

的背景知识

entryComponent是命令性的任何组件角负载。您可以通过在entryComponent或路由定义中引导来声明NgModule

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

Documentation在下面说

  

为了对比两种类型的组件,有一些组件   包含在模板中,是声明性的。另外,   您必须强制加载某些组件;即进入   组件。

现在回答您有关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);

答案 5 :(得分:0)

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

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

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

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