繁体   English   中英

在材质对话框中重用现有的 Angular 组件

[英]Reusing existing Angular Component inside material Dialog

我有一个由@Input()传递数据的现有组件ResultGridComponent 我想对MatDialog使用相同的组件。 因此,我在ResultGridComponent组件的构造函数中添加了@Inject(MAT_DIALOG_DATA) data

constructor(private spinner: EdpLoaderService, private dialog: MatDialog, @Optional() @Inject(MAT_DIALOG_DATA) data) {}

但是,当按照不是对话框的常规用法调用组件时,我收到以下错误:

ERROR 错误:StaticInjectorError(AppModule)[ResultGridComponent -> InjectionToken MatDialogData]: StaticInjectorError(Platform: core)[ResultGridComponent -> InjectionToken MatDialogData]: NullInjectorError: No provider for InjectionToken MatDialogData!

我很确定我已经导入了所有需要的模块。 因为我为对话框创建了一个单独的组件并将数据传递给它并且它工作正常。 但我想重用该组件。 而且我很确定当我将子组件的构造函数调用为常规组件并且构造函数没有获得调用者传递给它的MatDialogData时,会出现此错误。

在某些情况下,我会在 @Inject(MAT_DIALOG_DATA) 之前使用 @Optional()。

  constructor(
    @Optional() @Inject(MAT_DIALOG_DATA) dialogData: any
  ) {
    if (dialogData) {
     // here pass dialog data to the child component
    }
  }

我能够找到解决这种情况的方法。


问题陈述:我试图在 2 个不同的地方使用现有组件(我们称之为 ChildComponent)。 一个作为常规子组件,第二个作为 Material Dialog 内的组件。


挑战:要将数据传递给对话框组件,我们需要在子组件中使用@Inject(MAT_DIALOG_DATA)。 但是,当您在常规组件中注入 ChildComponent 时,您不会为“@Inject(MAT_DIALOG_DATA)”提供任何提供程序。 因此,它在启动时失败。 如果我们想在 Mat 对话框中使用 ChildComponent,我们确实需要 '@Inject(MAT_DIALOG_DATA)'。


解决方案:创建一个包装组件,我们称之为(ChildWrapperComponent)。 对于常规用例,直接在父组件中注入 ChildComponent。 而对于 Mat Dialog 用例,提供 ChildWrapperComponent

const dialogRef  = this.dialog.open(ChildWrapperComponent, {
                 width: '90%',
                 disableClose: false,
                 data: {
                   fileName: this.fileName,
                   results: this.results
                 }
               } );

现在您可以使用 @Inject(MAT_DIALOG_DATA) 数据在 ChildWrapperComponent 中获取数据

constructor(private spinner: EdpLoaderService, private dialog: MatDialog,
@Inject(MAT_DIALOG_DATA) data,
private dialogRef: MatDialogRef<ChildWrapperComponent>) {
this.setInputData(data);

}

一旦在 ChildWrapperComponent 中有数据,就将子组件注入 Wrapper 并使用 @Input() 传递数据。

我是 Angular 的新手。 非常感谢更好或不同的解决方案。

在阅读了依赖注入提供者之后,我通过添加这样的提供者来解决它

@Component({
  ...
  ...
  providers: [
    { provide: MatDialogRef, useValue: this },
  ]
})

在此之后,如果定期加载,我的组件从路由解析器读取数据,如果在另一个组件的对话框中加载,则从注入的MAT_DIALOG_DATA读取数据。

面临错误

ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(n)[InjectionToken MatDialogData -> InjectionToken MatDialogData -> InjectionToken MatDialogData]:
  NullInjectorError: No provider for InjectionToken MatDialogData!

通过在提供者列表中添加“MatDialogRef”来解决,并且

@Component({
  ...
  ...
  providers: [
    { provide: MatDialogRef, useValue: this },
  ]
})

还在组件构造函数的@Inject(MAT_DIALOG_DATA) 前面添加了@Optional 装饰器

constructor ( @Optional() @Inject(MAT_DIALOG_DATA) public dialogData: any ) { }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM