webentwicklung-frage-antwort-db.com.de

Angular2 Material Dialog hat Probleme - Haben Sie es zu @ NgModule.entryComponents hinzugefügt?

Ich versuche, die Dokumente auf https://material.angular.io/components/component/dialog zu befolgen, aber ich kann nicht verstehen, warum das folgende Problem vorliegt.

Ich habe das Folgende an meiner Komponente hinzugefügt:

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

In meinem Modul habe ich hinzugefügt 

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

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

Trotzdem bekomme ich diesen Fehler ....

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
195
Tampa

Sie müssen dynamisch erstellte Komponenten zu entryComponents in Ihrem @NgModule hinzufügen.

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

Hinweis: In einigen Fällen entryComponents unter faul geladene Module funktionieren nicht, da dies in einem Workaround in Ihrem app.module (root) geschieht

501
eko

Sie müssen entryComponents unter @NgModule verwenden.

Dies ist für dynamisch hinzugefügte Komponenten, die mit ViewContainerRef.createComponent() hinzugefügt werden. Durch das Hinzufügen zu entryComponents wird der Offline-Vorlagen-Compiler angewiesen, sie zu kompilieren und für sie Fabriken zu erstellen.

Die in Routenkonfigurationen registrierten Komponenten werden automatisch zu entryComponents hinzugefügt, da router-outlet auch ViewContainerRef.createComponent() verwendet, um geroutete Komponenten zum DOM hinzuzufügen.

So wird Ihr Code sein

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

Dies geschieht, weil dies eine dynamische Komponente ist und Sie sie nicht zu entryComponents unter @NgModule hinzugefügt haben.

Einfach dort hinzufügen:

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

Schauen Sie sich an, wie Angular Team im Kommentar über entryComponents spricht:

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

Gibt eine Liste von .__ an. Komponenten, die beim Definieren dieses Moduls kompiliert werden sollen. Zum Für jede hier aufgeführte Komponente erstellt Angular eine ComponentFactory und Speichern Sie es im ComponentFactoryResolver.

Dies ist auch die Liste der Methoden auf @NgModule, einschließlich entryComponents...

Wie Sie sehen, sind alle optional (siehe Fragezeichen), einschließlich entryComponents, die ein Array von Komponenten akzeptieren:

@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
})
9
Alireza

Wenn Sie versuchen, MatDialog in einem Service zu verwenden, nennen wir es 'PopupService' und dieser Service ist in einem Modul definiert mit:

@Injectable({ providedIn: 'root' })

dann kann es nicht funktionieren. Ich benutze Lazy Loading, bin aber nicht sicher, ob das relevant ist oder nicht.

Sie müssen:

  • Geben Sie Ihre PopupService direkt an die Komponente an, die Ihr Dialogfeld öffnet - mithilfe von [ provide: PopupService ]. Dies ermöglicht die Verwendung (mit DI) der Instanz MatDialog in der Komponente. Ich denke, die Komponente, die open aufruft, muss sich in demselben Modul befinden wie die Dialogkomponente in dieser Instanz.
  • Verschieben Sie die Dialogkomponente in Ihr app.module (wie in anderen Antworten bereits erwähnt wurde).
  • Übergeben Sie eine Referenz für matDialog, wenn Sie Ihren Dienst anrufen.

Entschuldigen Sie meine durcheinandergebrachte Antwort, der Punkt ist, dass es der providedIn: 'root' ist, der Dinge kaputt macht, weil MatDialog eine Komponente huckeln muss.

3
Simon_Weaver

Die Integration des Materialdialogs ist zwar möglich, aber ich habe festgestellt, dass die Komplexität eines solchen trivialen Merkmals ziemlich hoch ist. Der Code wird komplexer, wenn Sie versuchen, nicht triviale Funktionen zu erreichen.

Aus diesem Grund habe ich am Ende PrimeNG Dialog verwendet, das ich sehr einfach finden konnte:

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

Fügen Sie einfach Ihren Dialog in das HTML Ihrer Komponente ein:

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

PrimeNG PrimeFaces Dokumentation ist leicht zu verfolgen und sehr präzise.

Sie müssen es zu entryComponents hinzufügen, wie in docs angegeben.

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

Hier ist ein vollständiges Beispiel für App-Modul-Datei, deren Dialog als entryComponents definiert ist

0
yuval.bl

In meinem Fall habe ich meine Komponente zu Deklarationen und Eintragskomponenten hinzugefügt und die gleichen Fehler erhalten. Ich musste auch MatDialogModule zu Importen hinzufügen.

0
Dela

Im Falle eines verzögerten Ladens müssen Sie nur das MatDialogModule im Lazy Loading-Modul importieren. Dann kann dieses Modul die Eintragskomponente mit einem eigenen importierten MatDialogModule rendern:

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

Wenn Sie wie ich sind und diesen Thread anstarren, denken Sie: "Aber ich versuche nicht, eine Komponente hinzuzufügen, ich versuche, eine Wache/einen Dienst/eine Pipe usw. hinzuzufügen." dann ist das Problem wahrscheinlich, dass Sie einen falschen Pfad zu einem Routing-Pfad hinzugefügt haben. Das habe ich getan. Ich habe versehentlich einen Schutz zu der Komponente: Abschnitt eines Pfads anstelle des Abschnitts canActivate: hinzugefügt. Ich liebe IDE Autocomplete, aber Sie müssen etwas langsamer werden und aufpassen. Wenn Sie es absolut nicht finden können, führen Sie eine globale Suche nach dem Namen aus, über den Sie sich beschweren, und überprüfen Sie jede Verwendung, um sicherzustellen, dass Sie keinen Namen gefunden haben. 

0
LeftOnTheMoon