Apa itu entryComponents dalam angular ngModule?

131

Saya mengerjakan Ionicaplikasi ( 2.0.0-rc0) yang tergantung pada angular 2. Jadi pengantar baru ngModulesdisertakan. Saya menambahkan di app.module.ts.bawah saya .

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 {}

Apa yang entryComponentsdilakukan di sini? Componentssudah didefinisikan dalam declarations. Jadi apa perlunya mengulanginya? Apa yang akan terjadi jika saya tidak memasukkan komponen di sini?

raj
sumber
4
Angular menggunakan entryComponents untuk mengaktifkan "tree shaking" yaitu hanya mengkompilasi komponen yang sebenarnya digunakan dalam proyek alih-alih mengkompilasi semua komponen yang ada declareddi dalamnya ngModuletetapi tidak pernah digunakan. angular.io/docs/ts/latest/cookbook/… entrycomponents -
Samar

Jawaban:

155

Ini untuk komponen yang ditambahkan secara dinamis yang ditambahkan menggunakan ViewContainerRef.createComponent(). Menambahkannya untuk entryComponentsmemberi tahu kompilator template offline untuk mengkompilasi dan membuat pabrik untuk mereka.

Komponen yang terdaftar dalam konfigurasi rute ditambahkan secara otomatis ke entryComponents juga karena router-outletjuga digunakan ViewContainerRef.createComponent()untuk menambahkan komponen yang dialihkan ke DOM.

Compiler template offline (OTC) hanya membangun komponen yang benar-benar digunakan. Jika komponen tidak digunakan dalam template secara langsung, OTC tidak dapat mengetahui apakah mereka perlu dikompilasi. Dengan entryComponents Anda dapat memberitahu OTC untuk juga mengkompilasi komponen ini sehingga mereka tersedia saat runtime.

Apa itu komponen entri? (angular.io)

NgModule docs (angular.io)

Menentukan komponen yang harus dikompilasi juga ketika komponen ini didefinisikan. Untuk setiap komponen yang tercantum di sini, Angular akan membuat ComponentFactory dan menyimpannya di ComponentFactoryResolver.

Jika Anda tidak mencantumkan komponen yang ditambahkan secara dinamis ke entryComponents Anda akan mendapatkan pesan kesalahan tentang pabrik yang hilang karena Angular tidak akan membuatnya.

Lihat juga https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html

Günter Zöchbauer
sumber
12
terus terang, saya tahu jawabannya 100% benar tetapi pergi penjaga untuk saya, bisakah Anda menjelaskan lebih lanjut?
Pankaj Parkar
26
Sulit untuk mengatakan apa yang tidak jelas. Compiler template offline (OTC) hanya membangun komponen yang benar-benar digunakan. Jika komponen tidak digunakan dalam template secara langsung, OTC tidak dapat mengetahui apakah mereka perlu dikompilasi. Dengan entryComponentsAnda dapat memberitahu OTC untuk juga mengkompilasi komponen ini sehingga mereka tersedia saat runtime.
Günter Zöchbauer
3
stackoverflow.com/questions/36325212/… akan menjadi contoh seperti itu
Günter Zöchbauer
2
Jadi secara umum, jika komponen terdaftar di declarationsdalamnya juga harus terdaftar entryComponents, kan?
omnomnom
1
hanya jika komponen ditambahkan secara dinamis dengan createComponentdalam kode Anda atau misalnya router yang juga menggunakan thod API untuk menambahkan komponen.
Günter Zöchbauer
30

Anda tidak akan mendapatkan penjelasan yang lebih baik daripada dokumen Sudut: entri-komponen dan ngmodule-faq .

Dan di bawah ini adalah penjelasan dari dokumen sudut.

Komponen entri adalah komponen apa pun yang memuat Angular secara imperatif berdasarkan jenis.

Komponen yang dimuat secara deklaratif melalui pemilihnya bukan komponen entri.

Sebagian besar komponen aplikasi dimuat secara deklaratif. Angular menggunakan pemilih komponen untuk menemukan elemen dalam templat. Ini kemudian membuat representasi HTML dari komponen dan memasukkannya ke DOM pada elemen yang dipilih. Ini bukan komponen entri.

Beberapa komponen hanya dimuat secara dinamis dan tidak pernah direferensikan dalam templat komponen.

Root bootstrapped AppComponentadalah komponen entri. Benar, pemilihnya cocok dengan tag elemen di index.html. Tetapi index.htmlbukan komponen template danAppComponent pemilih tidak cocok dengan elemen di komponen komponen apa pun.

Angular memuat AppComponent secara dinamis karena ia terdaftar berdasarkan jenis @NgModule.bootstrap atau ditingkatkan secara imperatif dengan metode ngDoBootstrap modul.

Komponen dalam definisi rute juga merupakan komponen entri. Definisi rute mengacu pada komponen berdasarkan jenisnya. Router mengabaikan pemilih komponen yang dirutekan (jika ada) dan memuat komponen secara dinamis menjadi a RouterOutlet.

Kompiler tidak dapat menemukan komponen entri ini dengan mencari mereka di templat komponen lainnya. Anda harus menceritakannya dengan menambahkannya ke entryComponentsdaftar.

Angular secara otomatis menambahkan jenis komponen berikut ke modul entryComponents:

  • Komponen dalam @NgModule.bootstrapdaftar.
  • Komponen yang dirujuk dalam konfigurasi router.

Anda tidak perlu menyebutkan komponen-komponen ini secara eksplisit, meskipun melakukannya tidak berbahaya.

Mav55
sumber
Saat ini dokumen sudut tidak tersedia, jadi terima kasih untuk itu!
Caelum
Ini sepertinya tidak menyebutkan bahwa komponen dalam konfigurasi rute secara otomatis ditambahkan ke entryComponents (jadi Anda biasanya tidak perlu mendefinisikannya).
Connor
Jika kita membuat komponen untuk digunakan sebagai EntryComponentapakah kita harus menghapus selectoratribut? (karena itu tidak akan digunakan)
Ronan
24

Jawaban lain menyebutkan ini tetapi ringkasan dasarnya adalah:

  • itu diperlukan ketika Komponen TIDAK digunakan di dalam template html <my-component />
  • Misalnya ketika menggunakan komponen dialog Material Sudut Anda menggunakan komponen secara tidak langsung.

Komponen dialog material dibuat di dalam kode TS dan bukan template:

    const dialogRef = this.dialog.open(MyExampleDialog, { width: '250px' });
  }

Ini mengharuskan Anda untuk mendaftarkannya sebagai komponen entri:

  • entryComponents: [MyExampleDialog]

Kalau tidak, Anda mendapatkan kesalahan:

  • ERROR Error: No component factory found for MyExampleDialog. Did you add it to @NgModule.entryComponents?
Mike R
sumber
2
Penjelasan terbaik di sini.
nop
3

Entri entryComponents digunakan untuk mendefinisikan hanya komponen yang tidak ditemukan dalam html dan dibuat secara dinamis. Angular memerlukan petunjuk ini untuk menemukan komponen entri dan mengkompilasinya.

Ada dua jenis utama komponen entri:

  • Komponen root yang di-bootstrap.
  • Komponen yang Anda tentukan dalam definisi rute.

Untuk informasi lebih rinci tentang komponen entri, silakan merujuk angular.io https://angular.io/guide/entry-components

Vivek
sumber
1

Sedikit Latar Belakang tentang entryComponent

entryComponentadalah komponen apa pun Beban sudut sangat penting. Anda dapat mendeklarasikan entryComponentdengan bootstrap di NgModuleatau dalam definisi rute.

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

Dokumentasi mengatakan di bawah ini

Untuk membedakan kedua jenis komponen, ada komponen yang termasuk dalam templat, yang bersifat deklaratif. Selain itu, ada komponen yang Anda muat secara imperatif; yaitu komponen entri.

Sekarang untuk menjawab pertanyaan spesifik Anda entryComponents

Ada entryComponentsarray dalam @NgModulefile. Anda dapat menggunakan ini untuk menambahkan entryComponentsjika komponen menggunakan bootstrap ViewContainerRef.createComponent().

Itu adalah Anda membuat komponen secara dinamis dan bukan dengan bootstrap atau dalam templat.

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

Pada Angular 9 entryComponents tidak lagi diperlukan berkat Ivy yang memungkinkan fitur ini menjadi usang dan karenanya dapat dihapus dari deklarasi modul.

API dan fitur yang sudah usang - entryComponentsdan ANALYZE_FOR_ENTRY_COMPONENTStidak lagi diperlukan

Sebelumnya, entryComponentsarray dalam NgModuledefinisi digunakan untuk memberi tahu kompiler komponen mana yang akan dibuat dan dimasukkan secara dinamis. Dengan Ivy, ini bukan persyaratan lagi dan entryComponentsarray dapat dihapus dari deklarasi modul yang ada. Hal yang sama berlaku untuk ANALYZE_FOR_ENTRY_COMPONENTStoken injeksi.

Ivy sudut

Ivy adalah nama kode untuk kompilasi dan rendering pipeline generasi terbaru Angular. Dengan rilis Angular versi 9, kompiler dan instruksi runtime baru digunakan secara default alih-alih kompiler dan runtime yang lebih lama, yang dikenal sebagai View Engine.

Abu
sumber