声明和entryComponents之间有什么区别

时间:2017-05-06 02:15:04

标签: angular

我在app.module.ts中有这个:

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中得到错误。

我的问题是,如果它们总是相同,那么对这些属性的需求是什么?我想我肯定在这里缺少一些观点。 entryComponents和声明何时会彼此不同?

6 个答案:

答案 0 :(得分:96)

var items = []; var toBeAdded = { test: 'test' }; var findItem = function() { for (var i = 0; i < items.length - 1; i++) { if (items[i].indexOf(toBeAdded) >= 0) { return true } else { return false } } } if (!findItem()) { items.push(toBeAdded); } else { alert('item already exists'); } console.log(items);数组用于定义组件,这些组件在html中找不到并使用entryComponents动态创建。 Angular需要这个提示来找到它们并进行编译。所有其他组件应该只在声明数组中列出。

Here's the documentation on angular site

答案 1 :(得分:22)

添加@Julia已回答此问题的内容。我想添加模态的用例。

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

示例module.ts类似于:

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

我们会将TheCompYouWantToRenderInsideModalComponent作为entryComponent传递,因为在编写网站代码时不会出现此组件(,即任何{{1}都不会有TheCompYouWantToRenderInsideModalComponent的选择器文件)。我们会将此HTML传递给模态,然后在打开模态时将其动态。如下所示:

component

*在onSomeButtonClickToOpenModal(){ this.modalService.openModal(TheCompYouWantToRenderInsideModalComponent); } 中,我们会创建服务以使用ModalModule并将ComponentFactoryResolver作为参数。之后,我们可以调用一个函数(称之为TheCompYouWantToRenderInsideModalComponent),它将打开&amp;使用openModal(componentType: ComponentType)

进行渲染

附注: ComponentFactoryResolver也会在Angular V6 entryComponent功能中扮演重要角色,用于同一目的。

答案 2 :(得分:3)

对于 Angular 9 或已明确启用 Ivy 的Angular 8

不再需要带有常春藤的条目组件,现在已弃用

答案 3 :(得分:1)

为此,您需要了解实际的角度 在创建组件时可以在后台工作。

您计划使用的任何组件以及指令和管道,都需要将它们添加到declarations的{​​{1}}中的@NgModule数组中(同时使用多个{{1 }},我们将要素模块导入app.module.ts modules数组中,并且app.module.ts的{​​{1}}数组中包含所有组件。

上述步骤对于使角度了解应用程序中的组件或组件和指令很重要,因为它不会自动扫描所有文件。 创建新组件后,您需要告诉它存在哪些组件。

仅此一项就只能使它有角度地意识到,以便当它在两个位置之一中找到它时就能够创建这样的组件。

  1. 如果在角度模板中找到组件的imports,则第一个位置将在模板中-> 然后基本上会查看该特定组件的feature module数组-> 找到那里,然后能够创建该组件。

  2. 要寻找该组件的角度的另一个位置是在declarations中的selector中,-> 当您指向某个组件时,角度也会在declarations数组中进行检查,并且-> 如果发现可以在其中创建并加载该组件。

现在默认情况下,不起作用的一个地方是您要在代码中手动创建组件时。就像您想像routs一样用rout config创建declarations时,也许仅在出现错误时出现,并且您都没有提及它的dynamic component在任何component factoryalert component 中。

现在,这里的angular不会自动到达声明数组。 它根本不这样做。 您可以对此抱怨。 还是这样。

您有意识地需要通知角度,在这种情况下,警报组件将需要在某个地方创建,并且角度基本上应该为此准备。

一般来说,只要在selectortemplate中找到一个组件,angular就会为创建做好准备。但是在我们的情况下,我们没有完成上述两件事之一,角度不会自行做好准备。

现在要告诉angular为创建该组件做准备,您需要为传递给rout config的对象添加一个特殊属性,除了template rout config等等。 该属性为Ngmodule,它是组件类型的数组,但仅是最终将在没有declarationsimport的情况下创建的那些组件。

但是随着Angular 9的发布,幕后进行了一些更改,并且为您完成了所有这些工作,您不再需要手动提及entry components

信贷-从马克西米利安·施瓦茨穆勒(MaximilianSchwarzmüller)的Udemy课程“ Angular the Complete Guide”中学习了这些概念。

答案 4 :(得分:0)

简而言之:

entryComponents存在的“真正”原因是摇树,而declarations主要存在于模块封装中。因此它们甚至不可比。如果摇晃不是我们关心的问题,那么将声明作为二者的单一来源,我们会很好。

更长的答案

您在components中创建的所有module都不会进入最终捆绑包。相反,只有使用templateselectorscomponents中声明的组件(由您或框架)添加到entryComponents数组中。

如公认的答案所述,您希望像使用ComponentFactoryResolver那样动态创建组件时添加组件。或者,当您在Route数组中声明组件或在其他命令式创建过程中,框架可以添加组件。

摘自官方文档:

  

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

     

如果某个组件不是输入组件,并且在模板中找不到,   摇树器会将其丢弃。因此,最好仅添加   真正是入门组件的组件,可帮助您保持应用程序的状态   尽可能修剪。

答案 5 :(得分:0)

入口组件是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>

将此组件添加到appmodule

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

最终

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