Angular Material和Jasmine: "InjectionToken MdDialogData的提供程序不存在!"

100

我有一个组件,旨在在Angular Material MdDialog中使用:

@Component({
  ...
})
export class MyComponent {

  constructor(@Inject(MAT_DIALOG_DATA) public data: any, public dialogRef: 
MdDialogRef<MyComponent>) {
...
  }


}

我正在尝试使用Jasmine进行单元测试:

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        SharedTestingModule,
      ],
      declarations: [
        MyComponent,
      ],
    })
    .compileComponents();
  }));

  ...
  
});

很不幸,我遇到了以下错误:

错误:没有提供者 InjectionToken MdDialogData!

SharedTestingModule 导入并导出了我的自定义 Angular Material 模块,该模块本身又导入并导出了 MdDialogModule。

我该如何摆脱这个错误?

非常感谢你!

Angular 4.2.4
Angular Material 2.0.0-beta.7
Jasmine 2.5.3

如果可注入的对象(在这种情况下为MdDialogData)为空或未定义(JS),或者MatDialog的某个组件为空,则始终会出现此类型的错误,因此无法创建它。例如:let dialogRef = this.dialog.open(DeleteDialogComponent, { data: row.name //<-如果在此处放置i.e 4值,则会出现错误:InjectionToken MatDialogData没有提供程序,在这种情况下,DeleteDialogComponent继承自MatDialogRef,而MatDialogRef具有MAT_DIALOG_DATA作为可注入对象! }); - Aly González
8个回答

171

我添加了这个:

providers: [
    { provide: MAT_DIALOG_DATA, useValue: {} },
    // { provide: MdDialogRef, useValue: {} }, --> deprecated
    { provide: MatDialogRef, useValue: {} } ---> now
]

它有效 :)

感谢 @methgaard 的帮助!


很高兴能帮忙,我的荣幸! :) - kodeaben
9
在较新的 Angular 版本中,MD_DIALOG_DATA 的名称已更改为 MAT_DIALOG_DATA - Yuri
1
你把这个添加在哪里了? - Shawn Mercado
1
MdDialogRef is now MatDialogRef - smoq
此回答已过时,请查看其他评论。 - O-9
显示剩余3条评论

102

对于使用最新的Material组件的Angular 5

 import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';

 providers: [
     { provide: MAT_DIALOG_DATA, useValue: {} },
     { provide: MatDialogRef, useValue: {} }
 ]

对我来说完美地工作了..无法弄清如何从@angular/Material导入MAT_DIALOG_DATA - Rinktacular
这个完美地运作了。我在我的DialogRef组件中使用了@Inject(MAT_DIALOG_DATA) public data: any。我忘记在我的spec中声明它了。谢谢! - XenoX

15

试试这个

beforeEach(async(() => {
 TestBed.configureTestingModule({
   imports: [
     SharedTestingModule,
   ],
   declarations: [
     MyComponent,
   ],
   providers: [ <-- here
    {
     provide: MdDialogData,
     useValue: {},
    }
   ] <-- to here 
 })
 .compileComponents();
}));

请告诉我进展如何


13

更新一下,对于那些使用带有前缀“Mat”的标签的人,这也是可复制的。

providers: [{provide: MAT_DIALOG_DATA, useValue: {}}, 
{provide: MatDialogRef, useValue: {}}]

6
你可以使用 Angular 可选装饰器,我之前也遇到过这个问题。
如果组件不用作 弹出窗口,请尝试此代码片段。
constructor(
  @Optional() public dialogRef: MatDialogRef<PopupComponent>,
  @Optional() @Inject(MAT_DIALOG_DATA) public data: any
) {}

对我有用!!! 我有一个组件,我以正常方式加载它,有时也将其作为对话框加载。 因此,在正常加载中, *@Inject(MAT_DIALOG_DATA) public data: any * 为空,并且无法工作。 - Luke Matafi

4

你可以在jasmine测试中注入MAT_DIALOG_DATA / MAT_BOTTOM_SHEET_DATA而无需指定提供程序。你只需要确保被注入的值是非空的。如果它为空,编译器会将空值误认为是不存在的提供程序,从而导致出现“找不到提供程序”的错误。


这正是我的问题(使用 Angular 8.x) - Pianoman

1

请在<x>.component.spec.tsproviders下尝试添加以下内容:

{ provide: MatDialog, useValue: {} }

在某些情况下,你还需要:

{ provide: MatDialogRef, useValue: {} }

(这种方式适用于我的 Angular 11 项目)


0

没有 InjectionToken MatDialogData 的提供程序!当我们运行测试用例时,如果在所在组件使用 @Inject(MAT_DIALOG_DATA) public value: string 引用 matdialog ,将会出现此错误。

请在 spec.ts 文件中添加以下代码:

providers: [MatDialogModule, { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: MatDialogRef, useValue: {} }]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接