NullInjectorError: No provider for MatDialogRef

2020-03-01 02:35发布

I can't inject MatDialogRef as it described in documentation: https://material.angular.io/components/dialog/overview

When i'm trying to do it i'v got error:

ERROR Error: StaticInjectorError[MatDialogRef]: StaticInjectorError[MatDialogRef]: NullInjectorError: No provider for 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, {});
    }
}

registration.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
			);
	}
}

6条回答
Anthone
2楼-- · 2020-03-01 03:16

It could be due to you not including a Web Animations API polyfill which is required for Angular animations to work since it relies on the API.

Here's a caniuse for the browsers that support it natively. Currently only Chrome, Firefox and Opera support the Web Animations API.

Anyway, you have to follow these steps to get a polyfill:

  1. In the terminal, type the following in your console:

    npm install web-animations-js
    
  2. Once you have finished installing, uncomment the line for Angular Animations in polyfills.ts (or add it if it's not there):

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

Alternatively, you can try importing the modules from the separate endpoints, like so:

From:

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

To:

import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog';
查看更多
你好瞎i
3楼-- · 2020-03-01 03:20

I had this error when adding dialogs to a service to be shared in many components. Just to clarify, the error wasnt present in the application before moving dialogs to the service. The solution was to include a custom provider MatDialogRef in the main module

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

With this provider the service worked as a singleton with my dialogs to be shared and the provider error was gone.

查看更多
老娘就宠你
4楼-- · 2020-03-01 03:21
  • In your module: importing only MatDialogModule from angular/material is sufficient. Not required to import and provide: MatDialogRef
  • In your code where DialogComponent import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material';
  • The above are the steps that I have followed. Not sure why you need to import it from the Dialog
  • But, could you please clarify which selector you have used in your html/template? If you have used the "registration-component" in your template, that could be the reason why you would get this error. I tried out the exact same example out of the Material guide. I accidentally used the 'dialog-overview-example-dialog' instead of the 'dialog-overview-example'. = I got the same error you have got.
查看更多
地球回转人心会变
5楼-- · 2020-03-01 03:28

The component passed to the MatDialog open method should have MatDialogRef injected in its constructor as done in the example.

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

}

I was injecting it in the component which was calling MatDialog::open rather than in the component passed to the open method which was causing this error.

查看更多
干净又极端
6楼-- · 2020-03-01 03:29

For me the problem was that I had added my Dialog component to some other HTML Template just to test it. Once I removed it, the error in OP went away and it just worked.

查看更多
仙女界的扛把子
7楼-- · 2020-03-01 03:32

Thanks to the @Edric, i'v solved the problem by importing MatDialogModule, MatDialog and MatDialogRef from @angular/material/dialog instead of @angular/material

查看更多
登录 后发表回答