tutorial example angular angular-material

example - El diálogo de material Angular2 tiene problemas. ¿Lo agregó a @ NgModule.entryComponents?



angular material navbar (9)

Debe agregarlo a entryComponents , como se especifica en los docs .

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

Aquí hay un ejemplo completo de un archivo de módulo de aplicación con un cuadro de diálogo definido como entryComponents .

Estoy tratando de seguir los documentos en https://material.angular.io/components/component/dialog pero no puedo entender por qué tiene el siguiente problema.

Agregué lo siguiente en mi componente:

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

En mi módulo agregué

import { HomeComponent,DialogResultExampleDialog } from ''./home/home.component''; @NgModule({ declarations: [ AppComponent, LoginComponent, DashboardComponent, HomeComponent, DialogResultExampleDialog ], // ...

Sin embargo, recibo este error ...

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


En caso de carga diferida, solo necesita importar MatDialogModule en el módulo cargado diferido . Entonces este módulo podrá representar el componente de entrada con su propio MatDialogModule importado:

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


En mi caso, agregué mi componente a las declaraciones y entryComponents y obtuve los mismos errores. También necesitaba agregar MatDialogModule a las importaciones.


Esto está sucediendo porque este es un componente dinámico y no lo entryComponents a entryComponents en @NgModule .

Simplemente agréguelo allí:

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

Mire cómo el equipo Angular habla sobre los entryComponents de entryComponents :

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

Especifica una lista de componentes que deben compilarse cuando se define este módulo. Para cada componente enumerado aquí, Angular creará un ComponentFactory y lo almacenará en ComponentFactoryResolver.

Además, esta es la lista de los métodos en @NgModule incluidos entryComponents ...

Como puede ver, todos ellos son opcionales (mire los signos de interrogación), incluidos entryComponents que aceptan una variedad de componentes:

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


Si bien es posible integrar el diálogo de material, descubrí que la complejidad de una característica tan trivial es bastante alta. El código se vuelve más complejo si está tratando de lograr características no triviales.

Por esa razón, terminé usando PrimeNG Dialog , que encontré bastante fácil de usar:

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

Simplemente agregue su cuadro de diálogo en el html de su componente:

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

La documentación de PrimeNG PrimeFaces es fácil de seguir y muy precisa.


Si eres como yo y estás mirando este hilo pensando "Pero no estoy tratando de agregar un componente, estoy tratando de agregar un protector / servicio / tubería, etc." entonces es probable que haya agregado el tipo incorrecto a una ruta de enrutamiento. Eso es lo que hice. Accidentalmente agregué un protector al componente: sección de una ruta en lugar de canActivate: sección. Me encanta el autocompletado IDE, pero hay que reducir la velocidad un poco y prestar atención. Si no puede encontrarlo, realice una búsqueda global del nombre del que se queja y observe cada uso para asegurarse de que no se equivoca con un nombre.


Si está intentando usar MatDialog dentro de un servicio, llamémoslo ''PopupService'' y ese servicio se define en un módulo con:

@Injectable({ providedIn: ''root'' })

entonces puede que no funcione. Estoy usando carga diferida, pero no estoy seguro de si eso es relevante o no.

Tienes que:

  • Proporcione su PopupService directamente al componente que abre su diálogo, usando [ provide: PopupService ] . Esto le permite usar (con DI) la instancia de MatDialog en el componente. Creo que el componente que llama a open debe estar en el mismo módulo que el componente de diálogo en esta instancia.
  • Mueva el componente de diálogo hacia su app.module (como han dicho algunas otras respuestas)
  • Pase una referencia para matDialog cuando llame a su servicio.

Disculpe mi respuesta confusa, el punto es que se providedIn: ''root'' que se está rompiendo porque MatDialog necesita recuperar un componente.


entryComponents agregar componentes creados dinámicamente a entryComponents dentro de su @NgModule

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

Nota: En algunos casos, entryComponents en módulos con carga diferida no funcionará, como solución alternativa, app.module en su app.module (root)


entryComponents usar entryComponents en @NgModule .

Esto es para componentes agregados dinámicamente que se agregan usando ViewContainerRef.createComponent() . Agregarlos a entryComponents le dice al compilador de plantillas fuera de línea que los compile y cree fábricas para ellos.

Los componentes registrados en las configuraciones de ruta también se agregan automáticamente a entryComponents porque el router-outlet también usa ViewContainerRef.createComponent() para agregar componentes enrutados al DOM.

Entonces tu código será como

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