web-dev-qa-db-fra.com

Le dialogue sur les matériaux angulaires2 a des problèmes - L’avez-vous ajouté à @ NgModule.entryComponents?

J'essaie de suivre les docs sur https://material.angular.io/components/component/dialog mais je ne comprends pas pourquoi il pose le problème ci-dessous?

J'ai ajouté le ci-dessous sur mon composant:

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

Dans mon module j'ai ajouté 

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

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

Pourtant, je reçois cette erreur ....

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

Vous devez ajouter des composants créés dynamiquement à entryComponents dans votre @NgModule

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

Remarque: Dans certains cas, entryComponents sous modules chargés paresseux ne fonctionnera pas car une solution de contournement les mettra dans votre app.module (racine)

501
eko

Vous devez utiliser entryComponents sous @NgModule.

Cela concerne les composants ajoutés dynamiquement à l'aide de ViewContainerRef.createComponent(). Les ajouter à entryComponents indique au compilateur de modèles hors ligne de les compiler et de créer des fabriques pour ceux-ci.

Les composants enregistrés dans les configurations d'itinéraire sont automatiquement ajoutés à entryComponents également, car router-outlet utilise également ViewContainerRef.createComponent() pour ajouter des composants routés au DOM.

Donc, votre code sera comme

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

Cela se produit car il s'agit d'un composant dynamic et vous ne l'avez pas ajouté à entryComponents sous @NgModule.

Ajoutez-le simplement ici:

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

Regardez comment l'équipe angulaire parle de entryComponents dans le commentaire:

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

Spécifie une liste de composants devant être compilés lors de la définition de ce module. Pour Angular créera une ComponentFactory et .__ pour chaque composant répertorié ici. stockez-le dans le ComponentFactoryResolver.

C'est aussi la liste des méthodes sur @NgModule, y compris entryComponents...

Comme vous le voyez, ils sont tous facultatifs (regardez les points d’interrogation), y compris entryComponents qui accepte un tableau de composants:

@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

Si vous essayez d'utiliser MatDialog dans un service - appelons-le 'PopupService' et ce service est défini dans un module avec:

@Injectable({ providedIn: 'root' })

alors cela peut ne pas fonctionner. J'utilise le chargement paresseux, mais je ne suis pas sûr que ce soit pertinent ou non.

Vous devez:

  • Fournissez votre PopupService directement au composant qui ouvre votre boîte de dialogue - en utilisant [ provide: PopupService ]. Cela lui permet d'utiliser (avec DI) l'instance MatDialog dans le composant. Je pense que le composant appelant open doit être dans le même module que le composant dialog dans cet exemple.
  • Déplacez le composant de dialogue vers votre app.module (comme l'ont dit d'autres réponses)
  • Transmettez une référence pour matDialog lorsque vous appelez votre service.

Excusez ma réponse brouillée, l’essentiel étant que c’est le providedIn: 'root' qui casse des problèmes, car MatDialog doit s’emparer d’un composant.

3
Simon_Weaver

Bien que l’intégration du dialogue sur le matériau soit possible, j’ai constaté que la complexité d’une caractéristique aussi triviale est assez élevée. Le code devient plus complexe si vous essayez d’obtenir des fonctionnalités non triviales.

Pour cette raison, j'ai fini par utiliser PrimeNG Dialog , que j'ai trouvé assez simple à utiliser:

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

Ajoutez simplement votre boîte de dialogue dans le code HTML de votre composant:

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

Documentation PrimeNG PrimeFaces est facile à suivre et très précise.

1

Vous devez l'ajouter à entryComponents, comme spécifié dans docs .

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

Voici un exemple complet pour un fichier de module d'application avec un dialogue défini comme entryComponents

0
yuval.bl

Dans mon cas, j'ai ajouté mon composant aux déclarations et à entryComponents et j'ai eu les mêmes erreurs. Je devais également ajouter MatDialogModule aux importations.

0
Dela

En cas de chargement paresseux, il suffit d'importer MatDialogModule dans le module chargé paresseux. Ensuite, ce module pourra rendre le composant d’entrée avec son propre importé MatDialogModule :

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

Si vous êtes comme moi et regardez ce fil de discussion en pensant "Mais je n'essaye pas d'ajouter un composant, j'essaye d'ajouter un garde/un service/un tuyau, etc." alors le problème est probablement que vous avez ajouté le type incorrect à un chemin de routage. C'est ce que j'ai fait. J'ai accidentellement ajouté un garde au composant: section d'un chemin au lieu de la section canActivate:. J'aime IDE autocomplete, mais vous devez ralentir un peu et faire attention. Si vous ne pouvez absolument pas le trouver, faites une recherche globale pour le nom dont il se plaint et examinez chaque utilisation pour vous assurer que vous n'avez pas laissé tomber un nom. 

0
LeftOnTheMoon