我正在开发一个取决于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
。那么重复它们的必要性是什么?如果我在这里不包含组件会怎么样?
答案 0 :(得分:117)
这适用于使用ViewContainerRef.createComponent()
添加的动态添加组件。将它们添加到entryComponents
会告诉离线模板编译器编译它们并为它们创建工厂。
路由配置中注册的组件也会自动添加到entryComponents
,因为router-outlet
也使用ViewContainerRef.createComponent()
将路由组件添加到DOM。
离线模板编译器(OTC)仅构建实际使用的组件。如果组件未直接在模板中使用,则OTC无法知道是否需要编译它们。使用entryComponents,您可以告诉OTC也编译这些组件,以便它们在运行时可用。
What is an entry component? (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)
其他答案都提到了这一点,但基本摘要是:
<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
注入令牌也是如此。
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