首页 文章

Angular2材质对话框有问题 - 您是否将其添加到@ NgModule.entryComponents?

提问于
浏览
180

我正在尝试关注https://material.angular.io/components/component/dialog上的文档,但我不明白它为什么会出现以下问题?

我在我的组件上添加了以下内容:

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

在我的模块中,我补充道

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

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

但我得到这个错误....

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

6 回答

  • 0

    您需要在 @NgModule 中为 entryComponents 添加动态创建的组件

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

    Note: 在某些情况下 lazy loaded modules 下的 entryComponents 将无效,因为解决方法将它们放入 app.module (根)

  • 1

    您需要在 @NgModule 下使用 entryComponents .

    这适用于使用 ViewContainerRef.createComponent() 添加的动态添加组件 . 将它们添加到entryComponents会告诉离线模板编译器编译它们并为它们创建工厂 .

    路由配置中注册的组件也会自动添加到 entryComponents ,因为 router-outlet 也使用 ViewContainerRef.createComponent() 将路由组件添加到DOM .

    所以你的代码就像

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

    发生这种情况是因为这是一个 dynamic component 而您没有将其添加到 @NgModule 下的 entryComponents .

    只需将其添加到那里:

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

    看看Angular团队如何在评论中谈论 entryComponents

    entryComponents?:Array <Type <any> | any []>指定在定义此模块时应编译的组件列表 . 对于此处列出的每个组件,Angular将创建一个ComponentFactory并将其存储在ComponentFactoryResolver中 .

    这也是 @NgModule 上的方法列表,包括 entryComponents ...

    如您所见,所有这些都是可选的(查看问号),包括接受一系列组件的 entryComponents

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

    虽然可以集成材料对话框,但我发现这种简单特征的复杂性非常高 . 如果您尝试实现非平凡的功能,代码会变得更加复杂 .

    出于这个原因,我最终使用PrimeNG Dialog,我发现它非常简单易用:

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

    只需将对话框添加到组件的html中:

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

    PrimeNG PrimeFaces documentation易于遵循且非常精确 .

  • 449

    如果你像我一样,并盯着这个线程思考“但我不是想添加一个组件,我试图添加一个警卫/服务/管道等”那么问题很可能是您在路由路径中添加了错误的类型 . 这就是我做的 . 我不小心为组件添加了一个警卫:路径的一部分而不是canActivate:部分 . 我喜欢IDE自动完成功能,但你必须放慢速度并注意 . 如果您无法找到它,请在全球范围内搜索它所抱怨的名称,并查看每个用法,以确保您没有使用名称 .

  • 0

    在我的例子中,我将我的组件添加到声明和entryComponents并得到了相同的错误 . 我还需要将MatDialogModule添加到导入 .

相关问题