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
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
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]
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
})
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:
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.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.
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
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.
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]
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.