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


232

我正在尝试关注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

Answers:


604

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

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

注意:在某些情况entryComponents下,延迟加载的模块将无法工作,因为一种解决方法是将其放入您的app.module(根)目录


9
谢谢!到处都在寻找这个。在我的特定情况下,我需要将组件添加declarations到中才能正常工作
Jasdeep Khalsa,

95
每当我想了解NgModule时,就会出现类似这样的情况,并使您想知道此框架是否需要如此复杂。至少错误消息有帮助。
daddywoodland '17

3
如果您已经在里面了怎么办?为什么会说他们没有?
山姆·亚历山大

1
@SamAlexander您的问题确实很广泛,不胜感激,但请大胆猜测;在懒加载模块中使用它们吗?
eko

1
延迟加载的模块中的对话框从2.0.0-
beta.2版本开始起作用

53

您需要entryComponents在下使用@NgModule

这用于使用添加的动态添加的组件ViewContainerRef.createComponent()。将它们添加到entryComponents会指示脱机模板编译器对其进行编译并为其创建工厂。

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

所以你的代码就像

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

gh ...我有两个对话框在其他方面是相同的,但是一个对话框有指向它的测试路径。我删除了该测试路由,并且确定……路由在“帮助”我。> :(
汤姆

@Sunil Garg我还有另一个问题。我的对话框显示出来,但它会在1秒内自动关闭。请帮我。
Priyanka C

10

发生这种情况是因为这是一个动态组件,您没有将其添加到entryComponentsunder @NgModule

只需在此处添加:

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

3
与我相同的情况,将不起作用:它显示:错误:找不到DialogConfirmComponent的组件工厂。您是否将其添加到@ NgModule.entryComponents?任何想法?
Nam Le

您需要将其插入ngAfterViewInit(来自@ angular / core)
Patryk Panek

8

如果您要MatDialog在服务内部使用-可以称之为'PopupService'服务,并且该服务在模块中定义为:

@Injectable({ providedIn: 'root' })

则可能无法正常工作。我正在使用延迟加载,但是不确定是否相关。

你必须:

  • PopupService使用-直接将您的文件提供给打开对话框的组件[ provide: PopupService ]。这允许它使用(带有DI)MatDialog组件中的实例。我认为open在这种情况下,组件调用必须与对话框组件位于同一模块中。
  • 将对话框组件移至您的app.module(如其他答案所述)
  • matDialog致电服务时传递参考。

对不起,我的回答混乱,关键是providedIn: 'root'因为MatDialog需要附带一个组件,这才是打破常规的事情。


有时候是这样的!确实添加了您要提供的服务,而不是查看entrycomponent,错误的错误消息!
tibi

我也遇到了同样的情况,但是从这个答案中我无法理解,解决方案是哪一点?还是全部3个都是必需的?
coding_idiot

我遇到了同样的问题
MJVM

4

如果是延迟加载,则只需要在延迟加载的模块中导入MatDialogModule。然后,此模块将能够使用其自己导入的MatDialogModule渲染入口组件:

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

1

同时整合材料对话框是可能的,我发现这样一个微不足道的功能复杂度是相当高的。如果您尝试实现非平凡的功能,则代码将变得更加复杂。

因此,我最终使用了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文档易于理解且非常精确。


您只需要不需要动态创建的组件,就不会遇到主题启动程序问题。如果您尝试(甚至使用primeng)创建使用动态组件创建的dialogservice-您将面临完全相同的问题……
DicBrus

1

您必须将其添加到docs中entryComponents指定的位置。

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

这是一个应用程序模块文件的完整示例,其中对话框定义为entryComponents


0

如果您像我一样,并且盯着这个线程思考:“但是我没有尝试添加组件,而是尝试添加防护/服务/管道等。” 那么问题很可能是您在路由路径中添加了错误的类型。那就是我所做的。我不小心在路径的component:部分而不是canActivate:部分中添加了防护。我喜欢IDE自动完成功能,但是您必须放慢速度并注意。如果您绝对找不到它,请对它抱怨的名称进行全局搜索,并查看每种用法,以确保您不会遗漏任何名称。


0

就我而言,我将组件添加到了声明和entryComponents中,并得到了相同的错误。我还需要将MatDialogModule添加到导入中。


0

如果有人需要从服务中调用Dialog,这里是解决问题的方法。我同意上面的一些回答,我的回答是如果有人可能遇到问题,则在服务中调用对话框。

创建一个服务,例如DialogService,然后将对话框函数移到服务内部,然后将dialogservice添加到您调用的组件中,如以下代码所示:

 @Component({
  selector: "app-newsfeed",
  templateUrl: "./abc.component.html",
  styleUrls: ["./abc.component.css",],
  providers:[DialogService]
})

否则你会报错

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.