为啥 Angular 要求我们在声明数组和 entryComponents 数组中声明动态组件?
Posted
技术标签:
【中文标题】为啥 Angular 要求我们在声明数组和 entryComponents 数组中声明动态组件?【英文标题】:Why Angular requires us to declare dynamic components in declarations array and entryComponents array?为什么 Angular 要求我们在声明数组和 entryComponents 数组中声明动态组件? 【发布时间】:2019-03-19 11:25:50 【问题描述】:我正在为我的一个项目实施动态组件。动态组件的概念是一旦需要它们就会进入内存,并且在任何模板中都没有引用。
根据官方docs的说法,我们在entryComponents
中声明了这些组件,以防止它们在摇树过程中被丢弃,因为它们没有模板引用。
下面是app.module.ts
,我在entryComponents
数组中声明了我的两个动态组件SlideOneComponent
和SlideTwoComponent
:
@NgModule(
declarations: [
AppComponent,
ButtonComponent,
AdDirective
],
imports: [
BrowserModule
],
providers: [],
entryComponents: [
SlideOneComponent,
SlideTwoComponent,
],
bootstrap: [AppComponent]
)
export class AppModule
上面app.module.ts
我收到以下错误:
只要将两个动态组件都添加到declarations
数组,上述错误就会消失。上述官方文档还说,我们不需要声明可从entryComponents
或bootstrap
组件访问的组件。我也访问了this 答案,但这似乎不够令人满意,因为它是关于 Ionic 的。
请帮助我知道我在这方面缺少什么。提前致谢! :)
【问题讨论】:
The aforementioned official docs also says that we do not need to declare components that are reachable from entryComponents or bootstrap component.
你能指出文档说明这一点的确切位置吗?
您必须在declarations
数组中声明任何组件。除此之外,入口组件还必须在entryComponents
数组(NgModule 或组件级别)中显式或通过bootstrap
数组或路由声明
【参考方案1】:
从这句话中可以看出(在阅读字里行间):
虽然 @NgModule 装饰器有一个 entryComponents 数组,但大多数 您不必显式设置任何条目组件的时间,因为 Angular 添加了 @NgModule.bootstrap 中列出的组件以及 自动路由定义到入口组件。
您将常用组件添加到 EntryComponents 数组中隐式,这意味着它们被添加到两个数组中 - Declarations 和 EntryComponents(而您只在 Declarations 数组中添加了它)。因此,您还必须将动态组件显式添加到两个数组中。
声明 目的是使指令(组件等)可用于模块中的其他类,并将其选择器与 html 匹配。
EntryComponents 告诉 Angular 创建一个 componentFactory,它是由编译器根据您在 @Component
装饰器中提供的元数据创建的,因此您以后可以在 createComponent()
中使用它。
正如所见,这两个数组的用途非常不同,并且两者都是创建组件所必需的。如果组件不是动态创建的,编译器会读取它的元数据并创建一个componentFactory,但是编译器不知道动态组件,所以你必须在它运行之前通知它动态组件,因为他只运行一次 - 在编译时:)
【讨论】:
但这很矛盾,因为根据文档,entryComponents 中声明的组件是可访问的,不需要声明。另一种方法是在声明数组中声明它,但如果无法从模板中引用的组件或通过 entryComponents 中的组件访问它,我们仍然需要在 entryComponents 中声明它。所以无论是什么情况,我都必须在两个数组中声明。我说对了吗?但是我的上述假设仍然不能清除理解。 也许您误读了某些内容,或者我没有看到文档声明它“不需要声明”。我用更多细节编辑了我的答案 根据文档:。 “对于生产应用程序,您希望加载尽可能少的代码。代码应仅包含您实际需要的类,并排除从未使用过的组件。因此,Angular 编译器仅生成可从 entryComponents 访问的组件的代码; 这意味着添加更多对@NgModule.declarations 的引用并不意味着它们一定会包含在最终包中。”。所以根据这个,即使我们只在 entryComponents 中添加动态组件,Angular 编译器也应该能够找到它,对吗? 同意,但是由于它不在声明数组中,它的选择器不会与html匹配,其他类将无法访问它。你的错误来自这里 -github.com/angular/angular/blob/master/packages/compiler/src/…。如您所见,它需要对 NgModel 的引用,因此编译器会找到您的组件但无法确定它属于哪里以上是关于为啥 Angular 要求我们在声明数组和 entryComponents 数组中声明动态组件?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在 C 中为数组声明和指向数组声明的指针动态分配的内存不同? [复制]
为啥 Angular 2 ngOnChanges 不响应输入数组推送
为啥 SoapClient 在文档/文字样式中使用 WSDL 返回带有额外关键元素的数组?