声明和 entry 之间的区别是什么

我的应用程序模块里有这个:

import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { HttpModule, Http } from '@angular/http';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { EliteApi } from '../shared/shared';
import { MyApp } from './app.component';
import { MyTeams, Tournaments, TeamDetails, Teams, TeamHome, Standings } from '../pages/pages';


import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';


@NgModule({
declarations: [
MyApp,
MyTeams,
TeamDetails,
Tournaments,
Teams,
TeamHome,
Standings
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp),
HttpModule
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
MyTeams,
TeamDetails,
Tournaments,
Teams,
TeamHome,
Standings
],
providers: [
HttpModule,
StatusBar,
SplashScreen,
{ provide: ErrorHandler, useClass: IonicErrorHandler },
EliteApi
]
})
export class AppModule { }

现在我的 declarationsentryComponents都是完全一样的。它们包含我为应用程序构建的所有页面/组件。如果我从任何属性中删除任何条目,在 angular2中会得到错误。

我的问题是,如果它们总是相同的,那么这些属性有什么必要呢?我觉得我肯定漏掉了什么。Entry 组件和声明何时会彼此不同?

44145 次浏览

entryComponents数组用于定义 html 中没有的 只有组件,这些组件是用 ComponentFactoryResolver动态创建的。Angular 需要这个提示来找到它们并编译。所有其他组件都应该在声明数组中列出。

这是角度站点的文档

添加@Julia 对这个问题的回答。我想添加 莫德尔的用例。


假设您有一个称为 ModalComponent的组件。为了使其更具可重用性,您希望传递一个组件名,并期望该组件在 ModalComponent * 中呈现。

样本 module.ts大致如下:

import:[ModalModule],  // As a best practice, we can create Modal as a separate Feature
entryComponent : [TheCompYouWantToRenderInsideModalComponent]

我们将通过 TheCompYouWantToRenderInsideModalComponent作为 entryComponent,因为这个组件将不存在,而编写网站代码(即在任何 ABC3文件中都不会有 TheCompYouWantToRenderInsideModalComponent的选择器)。我们将这个 component传递给 Modal,然后当模态被打开时,它将被呈现为 动态的。下面是这样的:

onSomeButtonClickToOpenModal(){
this.modalService.openModal(TheCompYouWantToRenderInsideModalComponent);
}

* 在 ModalModule中,我们将创建使用 ComponentFactoryResolver的服务,并将 TheCompYouWantToRenderInsideModalComponent作为参数。稍后,我们可以调用一个函数(称为 openModal(componentType: ComponentType)) ,它将使用 ComponentFactoryResolver打开并呈现


旁注: 为了同样的目的,entryComponent也将在角 V6 elements特性中扮演重要角色。

更新: 角度9

随着 Angular 9的发布,我们不再需要有 entryComponent,感谢 常春藤编译器

简而言之:

entryComponents存在的“真正”原因是动摇树,而 declarations存在的主要原因是模块封装。所以他们根本没有可比性。如果我们关心的不是动摇树木,那么我们可以将声明作为两者的单一来源。

长一点的答案

您在 module中创建的所有 components都不会进入到 final bundle。相反,只有在 template中使用 selectorscomponents声明的组件被添加到 entryComponents阵列(由您或框架)。

您可能希望在动态创建组件时添加该组件,就像接受答案中所说的使用 ComponentFactoryResolver一样。或框架可以添加组件时,您声明在路由数组或在其他命令式创建。

官方文件:

事实上,许多库声明和导出的组件您永远不会 例如,材料设计库将导出所有组件 因为它不知道你会使用哪一个。然而,它是 不太可能全部使用。对于那些你没有参考的, 摇树器从最终的代码包中删除这些组件。

如果组件不是条目组件,并且在模板中找不到, 摇树器会把它扔掉 。所以,最好只添加 组件是真正的入口组件,以帮助保持您的应用程序作为 尽可能修剪。

条目组件是 Angular 强制加载的任何组件,这意味着您没有按类型在模板中引用它。 例如:

@Component({
selector: 'app-entry-component', // <== component select tags
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppEntryComponent {
// <== Component Class
}

将此选择器添加到您正在使用的组件中

<app-entry-component></app-entry-component>

在应用程序模块中添加此组件

const routes: Routes = [
{
path: '',
component: ComponentClassName,
children: []
}
]

终于

@NgModule({
declarations: [
AppComponent
],
imports: [
...
],
providers: [],
bootstrap: [AppComponent],
entryComponents: [
AppEntryComponent
]
})
export class AppModule { }

对于显式启用 艾薇角度9或角8

不再需要使用 Ivy 的入口组件,现在已经废弃

为此,你需要了解,角度实际上 当涉及到创建组件时,它在幕后工作

任何组件以及指令和管道,您计划工作,您需要添加到您的 declarations阵列 @NgModuleapp.module.ts(当与多个 modules工作,我们导入功能模块在我们的 app.module.ts imports阵列,和 feature module有其 declarations阵列的所有组件)。

上面提到的步骤对于弄清楚什么是组件或者应用程序中有哪些组件和指令非常重要,因为它 不会自动扫描所有的文件。 在创建新组件之后,您需要告诉它存在哪些组件。

然而,仅此一项只能使角感知到它,因此当它在两个地方之一找到它时,它就能够创建这样一个组件-

  1. 如果在模板中有角度地找到一个组件的 selector,那么首先应该放在模板中—— > 然后,它基本上查看特定组件的 declarations数组—— > 发现能够在那里然后创建该组件。

  2. 角度会寻找这个组件的另一个地方是在你的 rout config中的 routs,—— > 当你指向一个分量的时候,在 declarations数组中角度也会检查它,并且—— > 如果它发现它能够在那里创建这样一个组件并加载它。

现在,没有默认工作的一个地方是当您想要在代码中手动创建组件时。比如当你想创建一个 dynamic componentcomponent factory,就像 alert component一样,只有在出现错误和 你既没有在任何 ABC4或 ABC5中提到它的 selector的时候才会显示出来。

现在,这里的 angle 不会自动触及声明数组。 它根本不会那样做。 你可以抱怨。 还是这个案子。

相反,你需要故意告诉角度,在这种情况下,警报组件将需要在某个地方创建,角度基本上应该为此做好准备。

一般来说,当它在 templaterout config中找到一个组件时,角就会为这个创造做好准备。但是在我们的例子中,因为我们没有做上面提到的两件事情中的任何一件,角就不会为它自己做好准备。

现在要告诉 angle 为创建该组件做好准备,除了 declarations import之外,还需要向传递给 Ngmodule的对象添加一个特殊属性,以此类推。 这个属性是 entry components,它是一个组件类型的数组,但是只有那些最终将在没有 routsselectors的情况下创建的组件。

但是随着 Angular 9的发布,在幕后做了一些改变,它为你做了所有这些工作,你不需要再手动提到 entry components了。

学分——从 Udemy 课程“角度完整指南”中学到这些概念。