我试图在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

当前回答

虽然整合素材对话是可能的,但我发现这样一个简单功能的复杂性相当高。如果您试图实现非平凡的特性,那么代码将变得更加复杂。

出于这个原因,我最终使用了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文档易于遵循并且非常精确。

其他回答

在惰性加载的情况下,你只需要在惰性加载模块中导入MatDialogModule。然后这个模块将能够用它自己导入的MatDialogModule渲染入口组件:

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

你需要在@NgModule下使用entryComponents。

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

在路由配置中注册的组件也会自动添加到entryComponents中,因为路由器出口也使用ViewContainerRef.createComponent()将路由组件添加到DOM中。

所以你的代码就像

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

虽然整合素材对话是可能的,但我发现这样一个简单功能的复杂性相当高。如果您试图实现非平凡的特性,那么代码将变得更加复杂。

出于这个原因,我最终使用了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文档易于遵循并且非常精确。

如果有人需要调用对话从服务这里是如何解决这个问题。 我同意上面的一些答案,我的答案是如果有人可能面临问题,在服务中调用对话。

创建一个服务,例如DialogService,然后将你的dialog函数移动到服务内部,并在你调用的组件中添加你的DialogService,如下所示:

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

否则就会出错

这是因为这是一个动态组件,你没有将它添加到@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
})