web-dev-qa-db-ja.com

角度ngModuleのentryComponentsとは何ですか?

私は2.0.0-rc0に依存するIonicアプリ(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は既にdeclarationsに定義されています。それで、それらを繰り返す必要性は何ですか?ここにコンポーネントを含めないとどうなりますか?

105
raj

これはViewContainerRef.createComponent()を使用して追加された動的に追加されたコンポーネント用です。それらをentryComponentsに追加すると、オフラインテンプレートコンパイラはそれらをコンパイルしてそれらのファクトリを作成するように指示されます。

router-outletはルーティングされたコンポーネントをDOMに追加するためにViewContainerRef.createComponent()も使用するため、ルート設定に登録されたコンポーネントは自動的にentryComponentsにも追加されます。

オフラインテンプレートコンパイラ(OTC)は、実際に使用されるコンポーネントのみを構築します。コンポーネントがテンプレートで直接使用されていない場合、OTCはそれらがコンパイルされる必要があるかどうかを知ることができません。 entryComponentsを使用すると、これらのコンポーネントも実行時に使用できるようにOTCにコンパイルするように指示できます。

エントリーコンポーネントとは何ですか?(angular.io)

NgModule docs(angular.io)

このコンポーネントが定義されているときにもコンパイルする必要があるコンポーネントを定義します。ここにリストされている各コンポーネントに対して、AngularはComponentFactoryを作成し、それをComponentFactoryResolverに格納します。

動的に追加されたコンポーネントをentryComponentsにリストしないと、Angularが作成されていないため、不足しているファクトリについてエラーメッセージが表示されます。

https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html もご覧ください。

120

あなたは説明を得られないでしょうAngular docs。

そして、以下は角度のあるドキュメントからの説明です。

エントリコンポーネントは、Angularが型によって命令的にロードされるコンポーネントです。

セレクタを介して宣言的にロードされたコンポーネントはエントリコンポーネントではありません。

ほとんどのアプリケーションコンポーネントは宣言的にロードされます。 Angularは、コンポーネントのセレクタを使用してテンプレート内の要素を見つけます。次に、コンポーネントのHTML表現を作成し、それを選択された要素のDOMに挿入します。これらはエントリコンポーネントではありません。

いくつかのコンポーネントは動的にロードされるだけで、コンポーネントテンプレートでは参照されません。

ブートストラップルートAppComponentはエントリコンポーネントです。 True、そのセレクタはindex.htmlの要素タグと一致します。しかしindex.htmlはコンポーネントテンプレートではなく、AppComponentセレクタはどのコンポーネントテンプレートの要素とも一致しません。

AngularはAppComponentを動的にロードします。これは、@NgModule.bootstrapでタイプ別にリストされているか、モジュールのngDoBootstrapメソッドを使用して命令型でブーストラップされているためです。

ルート定義内のコンポーネントもエントリコンポーネントです。ルート定義は、そのタイプによってコンポーネントを参照します。ルーターはルーティングされたコンポーネントのセレクターを無視し(それがあっても)、そのコンポーネントを動的にRouterOutletにロードします。

コンパイラはこれらのエントリコンポーネントを他のコンポーネントテンプレートで検索しても発見できません。 entryComponentsリストにそれらを追加することによってそれらについてそれを伝える必要があります。

Angularは自動的に次の種類のコンポーネントをモジュールのentryComponentsに追加します。

  • @NgModule.bootstrapリスト内のコンポーネント。
  • ルータ設定で参照されているコンポーネント.

これらのコンポーネントを明示的に言及する必要はありませんが、そうすることは無害です。

27
Mav55

他の答えはこれに言及しますが、基本的な要約は以下のとおりです。

  • hTMLテンプレート内でComponentが使用されていない場合に必要となります<my-component />
  • たとえば、Angular Materialダイアログコンポーネントを使用するときは、そのコンポーネントを間接的に使用します。

品目ダイアログコンポーネントは、テンプレートではなく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?
2
Mike R

EntryComponents配列は、htmlに見つからず、動的に作成されたコンポーネントのみを定義するために使用されます。 Angularでは、エントリコンポーネントを見つけてそれらをコンパイルするためにこのヒントが必要です。

エントリコンポーネントには、主に2つの種類があります。

  • ブートストラップされたルートコンポーネント.
  • ルート定義で指定したコンポーネント。

エントリコンポーネントに関する詳細情報については、angular.io https://angular.io/guide/entry-components を参照してください。

0
Vivek

entryComponentに関する背景情報

entryComponentは任意のコンポーネントAngularであり、命令的にロードされます。 entryComponentまたはルート定義でブートストラップすることにより、NgModuleを宣言できます。

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

ドキュメント は以下を言います

2つのタイプのコンポーネントを対比するために、テンプレートに含まれるコンポーネントが宣言的です。さらに、命令的にロードするコンポーネントがあります。つまり、エントリコンポーネントです。

entryComponentsに関する具体的な質問に答えましょう

@NgModuleファイルにentryComponents配列があります。コンポーネントがViewContainerRef.createComponent()を使用してブートストラップされている場合、これを使用してentryComponentsを追加できます。

つまり、ブートストラップやテンプレートではなく、コンポーネントを動的に作成しています。

const componentFactory = this.componentFactoryResolver.resolveComponentFactory(myComp.component);
const viewContainerRef = this.compHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(componentFactory);
0
Nipuna