Dialog materi Angular2 memiliki masalah - Apakah Anda menambahkannya ke @ NgModule.entryComponents?

232

Saya mencoba mengikuti dokumen di https://material.angular.io/components/component/dialog tapi saya tidak mengerti mengapa ada masalah di bawah ini?

Saya menambahkan di bawah ini pada komponen saya:

@Component({
  selector: 'dialog-result-example-dialog',
  templateUrl: './dialog-result-example-dialog.html',
})
export class DialogResultExampleDialog {
  constructor(public dialogRef: MdDialogRef<DialogResultExampleDialog>) {}
}

Dalam modul saya, saya menambahkan

import { HomeComponent,DialogResultExampleDialog } from './home/home.component';

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    DashboardComponent,
    HomeComponent,
    DialogResultExampleDialog
  ],

// ...

Namun saya mendapatkan kesalahan ini ....

EXCEPTION: Error in ./HomeComponent class HomeComponent - inline template:53:0 caused by: No component factory found for DialogResultExampleDialog. Did you add it to @NgModule.entryComponents?
    ErrorHandler.handleError @ error_handler.js:50
    next @ application_ref.js:346
    schedulerFn @ async.js:91
    SafeSubscriber.__tryOrUnsub @ Subscriber.js:223
    SafeSubscriber.next @ Subscriber.js:172
    Subscriber._next @ Subscriber.js:125
    Subscriber.next @ Subscriber.js:89
    Subject.next @ Subject.js:55
    EventEmitter.emit @ async.js:77
    NgZone.triggerError @ ng_zone.js:329
    onHandleError @ ng_zone.js:290
    ZoneDelegate.handleError @ zone.js:246
    Zone.runTask @ zone.js:154
    ZoneTask.invoke @ zone.js:345
    error_handler.js:52 ORIGINAL EXCEPTION: No component factory found for DialogResultExampleDialog. Did you add it to @NgModule.entryComponents?
    ErrorHandler.handleError @ error_handler.js:52
    next @ application_ref.js:346
    schedulerFn @ async.js:91
    SafeSubscriber.__tryOrUnsub @ Subscriber.js:223
    SafeSubscriber.next @ Subscriber.js:172
    Subscriber._next @ Subscriber.js:125
    Subscriber.next @ Subscriber.js:89
    Subject.next @ Subject.js:55
    EventEmitter.emit @ async.js:77
    NgZone.triggerError @ ng_zone.js:329
    onHandleError @ ng_zone.js:290
    ZoneDelegate.handleError @ zone.js:246
    Zone.runTask @ zone.js:154
    ZoneTask.invoke @ zone.js:345
Tampa
sumber

Jawaban:

604

Anda perlu menambahkan komponen yang dibuat secara dinamis ke entryComponentsdalam@NgModule

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    DashboardComponent,
    HomeComponent,
    DialogResultExampleDialog        
  ],
  entryComponents: [DialogResultExampleDialog]

Catatan: Dalam beberapa kasus di entryComponentsbawah modul yang dimuat malas tidak akan berfungsi, karena solusi menempatkannya di app.module(root) Anda

eko
sumber
9
Terima kasih! Sedang mencari di mana-mana untuk ini. Dalam kasus khusus saya, saya juga perlu menambahkan komponen ke declarationsuntuk mendapatkan sesuatu untuk bekerja
Jasdeep Khalsa
95
Setiap kali saya merasa seperti saya mendapatkan sekitar NgModule sesuatu seperti ini muncul dan membuat Anda bertanya-tanya apakah kerangka kerja ini harus sangat kompleks. Setidaknya pesan kesalahan sangat membantu.
daddywoodland
3
Bagaimana jika Anda sudah memilikinya di sana? mengapa dikatakan mereka tidak?
Sam Alexander
1
@SamAlexander pertanyaan Anda sangat luas karena Anda akan menghargai tetapi mengambil tebakan liar; Apakah Anda menggunakannya di dalam modul malas Anda?
eko
1
dialog dalam modul malas dimuat berfungsi pada 2.0.0-beta.2
charlie_pl
53

Anda harus menggunakan di entryComponentsbawah @NgModule.

Ini untuk komponen yang ditambahkan secara dinamis yang ditambahkan menggunakan ViewContainerRef.createComponent(). Menambahkannya ke entryComponents memberi tahu kompiler template offline untuk mengkompilasi mereka dan membuat pabrik untuk mereka.

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

Jadi kode Anda akan seperti

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    DashboardComponent,
    HomeComponent,
    DialogResultExampleDialog        
  ],
  entryComponents: [DialogResultExampleDialog]
Sunil Garg
sumber
Ugh ... Saya punya dua dialog yang sebaliknya identik tetapi satu saya memiliki rute uji yang menunjuk ke sana. Saya menghapus rute pengujian itu dan tentu saja ... peruteannya "membantu" saya. > :(
Tom
@Sunil Garg Saya punya masalah lain. Dialog saya tampil tetapi secara otomatis ditutup dalam 1sec. Tolong bantu aku.
Priyanka C
10

Ini terjadi karena ini adalah komponen dinamis dan Anda tidak menambahkannya di entryComponentsbawah @NgModule.

Cukup tambahkan di sana:

@NgModule({
  /* ----------------- */
  entryComponents: [ DialogResultExampleDialog ] // <---- Add it here

Lihatlah bagaimana tim Angular berbicara tentang entryComponents:

entryComponents?: Array<Type<any>|any[]>

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

Juga, ini adalah daftar metode @NgModuletermasuk entryComponents...

Seperti yang Anda lihat, semuanya adalah opsional (lihat tanda tanya), termasuk entryComponentsyang menerima berbagai komponen:

@NgModule({ 
  providers?: Provider[]
  declarations?: Array<Type<any>|any[]>
  imports?: Array<Type<any>|ModuleWithProviders|any[]>
  exports?: Array<Type<any>|any[]>
  entryComponents?: Array<Type<any>|any[]>
  bootstrap?: Array<Type<any>|any[]>
  schemas?: Array<SchemaMetadata|any[]>
  id?: string
})
Alireza
sumber
3
kasus yang sama dengan saya dan tidak akan berfungsi: ini menunjukkan: Kesalahan: Tidak ada pabrik komponen yang ditemukan untuk DialogConfirmComponent. Apakah Anda menambahkannya ke @ NgModule.entryComponents? Ada ide?
Nam Le
Anda harus memasukkannya ke ngAfterViewInit (dari @ angular / core)
Patryk Panek
8

Jika Anda mencoba menggunakan MatDialogdi dalam layanan - sebut saja 'PopupService'dan layanan itu didefinisikan dalam modul dengan:

@Injectable({ providedIn: 'root' })

maka itu mungkin tidak berfungsi. Saya menggunakan pemuatan malas, tetapi tidak yakin apakah itu relevan atau tidak.

Kamu harus:

  • Berikan Anda PopupServicelangsung ke komponen yang membuka dialog Anda - menggunakan [ provide: PopupService ]. Ini memungkinkannya untuk menggunakan (dengan DI) MatDialoginstance dalam komponen. Saya pikir pemanggilan komponen openharus dalam modul yang sama dengan komponen dialog dalam contoh ini.
  • Pindahkan komponen dialog ke app.module Anda (seperti beberapa jawaban lain katakan)
  • Berikan referensi matDialogketika Anda menelepon layanan Anda.

Maafkan jawaban saya yang campur aduk, intinya adalah itu providedIn: 'root'yang melanggar hal-hal karena MatDialog perlu mengembalikan komponen.

Simon_Weaver
sumber
ini terjadi! memang menambahkan layanan Anda untuk memberikan alih-alih melihat entri kesalahan, pesan kesalahan!
tibi
Terjadi hal yang sama untuk saya, tetapi saya tidak bisa mengerti dari jawaban ini, poin mana solusinya? Atau ketiganya diperlukan?
coding_idiot
Saya memiliki masalah yang sama
MJVM
4

Dalam hal pemuatan malas, Anda hanya perlu mengimpor MatDialogModule dalam modul pemuatan malas. Maka modul ini akan dapat membuat komponen entri dengan MatDialogModule yang diimpor sendiri :

@NgModule({
  imports:[
    MatDialogModule
  ],
  declarations: [
    AppComponent,
    LoginComponent,
    DashboardComponent,
    HomeComponent,
    DialogResultExampleDialog        
  ],
  entryComponents: [DialogResultExampleDialog]
Yuchao Wu
sumber
1

Sementara mengintegrasikan dialog materi mungkin , saya menemukan bahwa kompleksitas untuk fitur sepele seperti itu cukup tinggi. Kode menjadi lebih kompleks jika Anda mencoba untuk mencapai fitur yang tidak sepele.

Karena alasan itu, saya akhirnya menggunakan Dialog PrimeNG , yang menurut saya cukup mudah untuk digunakan:

m-dialog.component.html:

<p-dialog header="Title">
  Content
</p-dialog>

m-dialog.component.ts:

@Component({
  selector: 'm-dialog',
  templateUrl: 'm-dialog.component.html',
  styleUrls: ['./m-dialog.component.css']
})
export class MDialogComponent {
  // dialog logic here
}

m-dialog.module.ts:

import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { DialogModule } from "primeng/primeng";
import { FormsModule } from "@angular/forms";

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    DialogModule
  ], 
  exports: [
    MDialogComponent,
  ], 
  declarations: [
    MDialogComponent
  ]
})
export class MDialogModule {}

Cukup tambahkan dialog Anda ke html komponen Anda:

<m-dialog [isVisible]="true"> </m-dialog>

Dokumentasi PrimeNG PrimeFaces mudah diikuti dan sangat tepat.

Menelaos Kotsollaris
sumber
Anda tidak menghadapi masalah topik-pemula hanya sampai Anda tidak perlu komponen yang dibuat dinamis. Jika Anda mencoba (bahkan dengan primeng) membuat layanan dialog yang menggunakan pembuatan komponen dinamis - Anda akan menghadapi masalah yang sama persis ...
DicBrus
1

Anda harus menambahkannya entryComponents, sebagaimana ditentukan dalam dokumen .

@NgModule({
  imports: [
    // ...
  ],
  entryComponents: [
    DialogInvokingComponent, 
    DialogResultExampleDialog
  ],
  declarations: [
    DialogInvokingComponent,   
    DialogResultExampleDialog
  ],
  // ...
})

Berikut adalah contoh lengkap untuk file modul aplikasi dengan dialog yang didefinisikan sebagai entryComponents.

yuval.bl
sumber
0

Jika Anda seperti saya, dan menatap utas ini dengan berpikir, "Tapi saya tidak mencoba menambahkan komponen, saya mencoba menambahkan penjaga / layanan / pipa, dll." maka masalahnya kemungkinan Anda telah menambahkan jenis yang salah ke jalur perutean. Itulah yang saya lakukan. Saya tidak sengaja menambahkan pelindung ke bagian komponen: bagian jalur alih-alih bagian canActivate :. Saya suka IDE autocomplete tetapi Anda harus sedikit melambat dan memperhatikan. Jika Anda benar-benar tidak dapat menemukannya, lakukan pencarian global untuk nama yang dikeluhkannya dan lihat setiap penggunaan untuk memastikan Anda tidak tergelincir dengan nama.

LeftOnTheMoon
sumber
0

Dalam kasus saya, saya menambahkan komponen saya ke deklarasi dan entriComponents dan mendapat kesalahan yang sama. Saya juga perlu menambahkan MatDialogModule ke impor.

Dela
sumber
0

Jika seseorang perlu menelepon Dialog dari layanan di sini adalah cara mengatasi masalah tersebut. Saya setuju dengan beberapa jawaban di atas, jawaban saya adalah untuk memanggil dialog di layanan jika seseorang mungkin menghadapi masalah.

Buat layanan misalnya DialogService kemudian pindahkan fungsi dialog Anda di dalam layanan dan tambahkan layanan dialog Anda pada komponen yang Anda panggil seperti kode di bawah ini:

 @Component({
  selector: "app-newsfeed",
  templateUrl: "./abc.component.html",
  styleUrls: ["./abc.component.css",],
  providers:[DialogService]
})

jika tidak, Anda mendapatkan kesalahan

MJVM
sumber