91

我不能像文档中描述的那样注入 MatDialogRef:https ://material.angular.io/components/dialog/overview

当我尝试这样做时,我遇到了错误:

ERROR 错误:StaticInjectorError[MatDialogRef]:StaticInjectorError[MatDialogRef]:NullInjectorError:没有 MatDialogRef 的提供者!

app.module.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule }   from '@angular/forms';

import {
	MatInputModule,
	MatDialogModule,
	MatProgressSpinnerModule,
	MatButtonModule,
	MatDialog,
	MatDialogRef
} from '@angular/material';

import { ApiModule } from '../api/api.module';
import { RoutingModule } from '../routing/routing.module';

import { RegistrationComponent } from './components/registration.component';
import { LoginComponent } from './components/login.component';

import { AccountService } from './services/account.service';

@NgModule({
	imports: [
		BrowserModule,
		MatInputModule,
		MatDialogModule,
		MatProgressSpinnerModule,
		MatButtonModule,
		FormsModule,
		RoutingModule,
		ApiModule
	],
	declarations: [
		RegistrationComponent,
		LoginComponent
	],
	entryComponents: [
		LoginComponent,
		RegistrationComponent
	],
	providers: [
		AccountService,
		MatDialog,
		MatDialogRef
	]
})
export class AccountModule {}

home.component.ts

import { Component } from '@angular/core';

import { MatDialog } from '@angular/material';
import { RegistrationComponent } from '../account/components/registration.component';

@Component({
    moduleId: module.id.replace('compiled', 'app'),
    templateUrl: 'home.component.html'
})
export class HomeComponent
{
    constructor(private modalService: MatDialog) {}

    public openModal() : void
    {
        let dialog = this.modalService.open(RegistrationComponent, {});
    }
}

注册.component.ts

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { MatDialogRef } from '@angular/material/dialog';

import { User } from '../../../models/domain/User';
import { ApiUserService } from '../../api/entity-services/user.service';
import { AuthService } from '../../auth/auth.service';
import { AccountService } from '../services/account.service'

@Component({
	selector: 'registration-component',
	templateUrl: 'app/modules/account/templates/registration.component.html'
})
export class RegistrationComponent
{
	public user :User = new User();

	public errorMessage :string;

	public isLoading :boolean;

	constructor
	(
		private userService :ApiUserService,
		private authService :AuthService,
		private accountService :AccountService,
		private router :Router,
		public dialogRef :MatDialogRef<RegistrationComponent>
	)
	{
		this.isLoading = false;
	}

	public onSubmit(e) :void
	{
		e.preventDefault();
		this.isLoading = true;

		this.userService
			.Create(this.user)
			.subscribe(
				user =>
				{
					this.user.id = user.id;
					this.user.login = user.login;


					this.authService
						.Login(this.user)
						.subscribe(
							token =>
							{
								this.accountService.Load()
									.subscribe(
										account =>
										{
											this.user = account;
											this.isLoading = false;
											this.dialogRef.close();

											let redirectRoute = account.activeScopeId
												? `/scope/${account.activeScopeId}`
												: '/scope-list/';

											this.router.navigate([redirectRoute]);
										},
										error => this.errorMessage = <any>error
									);
							},
							error => this.errorMessage = <any>error
						);
				},
				error => this.errorMessage = <any>error
			);
	}
}

4

15 回答 15

141

将对话框添加到要在许多组件中共享的服务时出现此错误。只是为了澄清,在将对话框移动到服务之前,应用程序中不存在错误。MatDialogRef解决方案是在主模块中包含一个自定义提供程序

  import { DialogService } from './services/dialog.service';
  import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
  ...
  imports: [
    ...
    MatDialogModule
  ],
  providers: [
     {
       provide: MatDialogRef,
       useValue: {}
     },
     DialogService
  ],
  ...

有了这个提供者,该服务作为一个单例工作,我的对话框被共享并且提供者错误消失了。

于 2018-11-02T05:56:31.107 回答
28

感谢@Edric,我通过 importMatDialogModule和fromMatDialog而不是解决了这个问题MatDialogRef@angular/material/dialog@angular/material

于 2017-11-14T20:53:09.340 回答
19

例如,您正在使用app-checkout

如果您在“对话框”和“正常”方式app-checkout中使用组件添加正常的 html 文件,则可能会发生这种情况。

解决方案1:<app-checkout> </app-checkout>如果您不需要在html文件中以正常方式导入它,请删除

解决方案 2 在对话框和 html 文件中使用。而不是这个:

// ... something have selector: "app-checkout",
 constructor(
    public dialogRef: MatDialogRef<CheckoutComponent>,
    @Inject(MAT_DIALOG_DATA) public dialogData: any
  ) {}

您需要注入它(使其成为可选注入):

这边走:


  constructor(
    // only need the @Optional() before the public dialogRef 
    @Optional() public dialogRef: MatDialogRef<CheckoutComponent>, 
    @Inject(MAT_DIALOG_DATA) public dialogData: any
  ) {

  }

或者这样:

// ... the same above
  private dialogRef = null;
  private dialogData;
  constructor(private injector: Injector) {
      this.dialogRef = this.injector.get(MatDialogRef, null);
      this.dialogData = this.injector.get(MAT_DIALOG_DATA, null);
  }
于 2020-04-26T15:20:17.663 回答
5

只需@Optional()在您的 dialogRef 声明之前添加。

例如:

constructor(
    @Optional() public dialogRef: MatDialogRef<yourDialogComponentName>
) {
}
于 2021-03-23T12:23:01.223 回答
5

我有这个错误并修复它你需要做的是

  1. 检查您是否像这样在打字稿文件中插入了导入语句

    从“@angular/material/dialog”导入 {MAT_DIALOG_DATA, MatDialogRef};

  2. 检查构造函数

      constructor(@Optional() public dialogRef: MatDialogRef<GadgetAuthMessagesComponent>, @Inject(MAT_DIALOG_DATA) public message: string){ }
    
  3. 现在转到模块 .ts 并检查导入

    import {MAT_DIALOG_DATA, MatDialogModule, MatDialogRef} from '@angular/material/dialog';
    
  4. 在 module.ts 中,我们需要将 MatDialogModule 名称放在导入数组下

    MatDialog模块

  5. 现在终于完成了,我们必须更新提供者数组

      providers:
    [{
      provide: 'gadget-mlt',
      useValue: GadgetMltComponent,
  },
        {provide:MatDialogRef , useValue:{} },

        { provide: MAT_DIALOG_DATA, useValue: {} }

  ],

现在它应该工作了,希望这对某人有帮助!

于 2020-12-17T07:40:02.550 回答
4

这可能是由于您没有包含 Angular 动画工作所需的 Web Animations API polyfill,因为它依赖于 API。

这是原生支持它的浏览器的caniuse。目前只有 Chrome、Firefox 和 Opera 支持 Web Animations API。

无论如何,您必须按照以下步骤获取 polyfill:

  1. 在终端中,在控制台中键入以下内容:

    npm install web-animations-js
    
  2. 完成安装后,取消注释 Angular Animations 的行polyfills.ts(如果不存在,则添加它):

    import 'web-animations-js'; // Uncomment this line
    

或者,您可以尝试从单独的端点导入模块,如下所示:

从:

import { MatButtonModule, MatDialogModule } from '@angular/material';

至:

import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog';
于 2017-11-14T13:00:45.287 回答
3

component.ts 和 spec.ts 中的导入路径必须相同

例如:

// in the component and spec files
import { MatDialogRef } from '@angular/material/dialog';

或者

// in the component and spec files
import { MatDialogRef } from '@angular/material';
于 2021-04-23T13:04:54.827 回答
3
  • 在您的模块中:仅从 angular/material 导入 MatDialogModule 就足够了。不需要导入和提供:MatDialogRef
  • 在您的代码中 DialogComponentimport {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material';
  • 以上是我遵循的步骤。不知道为什么需要从对话框中导入它
  • 但是,您能否澄清一下您在 html/模板中使用了哪个选择器?如果您在模板中使用了“注册组件”,这可能就是您收到此错误的原因。我从材料指南中尝试了完全相同的示例。我不小心使用了“dialog-overview-example-dialog”而不是“dialog-overview-example”。= 我得到了和你一样的错误。
于 2017-11-23T12:16:31.520 回答
2

对我来说,问题是我已经将我的 Dialog 组件添加到其他一些 HTML 模板中只是为了测试它。一旦我删除它,OP中的错误就消失了,它就可以工作了。

于 2019-09-13T21:09:51.690 回答
1

从构造函数中删除 dialogRef:

https://stackblitz.com/edit/angular-dialog-update?file=src%2Fapp%2Fapp.component.ts

于 2020-08-24T21:15:23.947 回答
1

在注入垫对话框之前使用“@Optional()”的角度 12,如下所示:

 @Optional() @Inject(MAT_DIALOG_DATA) public data:any

并在主应用程序模块中添加了一些代码,如下所示:

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

此致。

于 2021-08-25T12:32:15.603 回答
0

这个错误一般是由于没有提供所需的模块造成的。将外部模块导入您使用外部模块组件的模块。这可能会解决问题。

于 2022-01-04T23:46:12.673 回答
0

此错误可能是由于MatDialogRef在调用 MatDialog::open 的组件中注入而不是在传递给 open 方法的组件中引起的。传递给 MatDialog open 方法的组件应该已MatDialogRef注入其构造函数,如示例中所做那样。

@Component({
  selector: 'dialog-overview-example-dialog',
  templateUrl: 'dialog-overview-example-dialog.html',
})
export class DialogOverviewExampleDialog {

  constructor(
    public dialogRef: MatDialogRef<DialogOverviewExampleDialog>,
    @Inject(MAT_DIALOG_DATA) public data: DialogData) {}

  onNoClick(): void {
    this.dialogRef.close();
  }

}
于 2019-08-06T00:56:55.467 回答
0

除了上述所有内容之外,如果您在应用程序的任何模板文件中引用了组件选择器,您也可能会收到此错误。MatDialog 组件只能由 MatDialog.dialog.open() 方法调用,而不是通过组件选择器

不幸的是,由于许多原因,可能会引发相同的错误消息。

于 2020-10-23T02:35:58.040 回答
0

显然我的代码中的一切都很好。问题是,在开发过程中,我的模态组件有一条时间路径,因此我可以像查看任何其他常规组件/视图一样查看它。在组件中,我有一个按钮触发以模态方式打开自身,因此我可以测试它实际打开时的外观。

所以我将打开对话框的代码移到了另一个组件,它似乎解决了这个问题。

于 2021-07-23T08:26:03.910 回答