programing

NullInjectorError: MatDialogRef에 대한 공급자가 없습니다.

abcjava 2023. 4. 26. 22:50
반응형

NullInjectorError: MatDialogRef에 대한 공급자가 없습니다.

설명서에 설명된 대로 MatDialogRef를 주입할 수 없습니다. https://material.angular.io/components/dialog/overview

이 작업을 수행하려고 할 때 오류가 발생합니다.

오류 오류: 정적 인젝터 오류[MatDialogRef]:정적 인젝터 오류 [MatDialogRef]:NullInjectorError: MatDialogRef!에 대한 공급자가 없습니다.

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

여러 구성 요소에서 공유할 서비스에 대화 상자를 추가할 때 이 오류가 발생했습니다.확인하기 위해 대화 상자를 서비스로 이동하기 전에 응용 프로그램에 오류가 발생하지 않았습니다.인 "Custom Provider"를 포함하는 이었습니다.MatDialogRef

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

이 공급자와 함께 서비스는 대화상자를 공유하는 싱글톤으로 작동했고 공급자 오류는 사라졌습니다.

@Edric 덕분에 수입을 통해 문제를 해결했습니다.MatDialogModule,MatDialog그리고.MatDialogRef@angular/material/dialog@angular/material

를 들어, 은 예들어사중경우를 합니다.app-checkout

'두 가지 방법으로 할 수 .app-checkout일반 html 파일에 있습니다.

제거 1: 제거<app-checkout> </app-checkout>HTML 파일에서 정상적인 방법으로 가져올 필요가 없다면,

대화 상자와 html 파일 모두에서 사용하는 솔루션 2.이 대신:

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

나는 이 오류를 가지고 있었고 그것을 수정했습니다 당신이 해야 하는 것입니다.

  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 이름을 넣어야 합니다.

    매트 대화 모듈

  5. 이제 마침내 그것이 완료되었습니다. 우리는 공급자 배열을 업데이트해야 합니다.

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

        { provide: MAT_DIALOG_DATA, useValue: {} }

  ],

이제 효과가 있을 것입니다. 이것이 누군가에게 도움이 되기를 바랍니다!

그냥추를 추가하세요.@Optional()대화 상자 Ref 선언 전에.

예:

constructor(
    @Optional() public dialogRef: MatDialogRef<yourDialogComponentName>
) {
}

아래와 같이 주입 매트 대화 상자 앞에 "@Optional()"을 사용한 각도 12에서:

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

메인 앱 모듈에 아래와 같은 코드가 추가되었습니다.

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

안부 전합니다.

Angular 애니메이션이 API에 의존하기 때문에 작동하는 데 필요한 Web Animations API 폴리필이 포함되어 있지 않기 때문일 수 있습니다.

다음은 기본적으로 지원하는 브라우저를 위한 사용법입니다.현재는 크롬, 파이어폭스, 오페라만 웹 애니메이션 API를 지원합니다.

어쨌든 폴리필을 얻으려면 다음 단계를 수행해야 합니다.

  1. 터미널에서 콘솔에 다음을 입력합니다.

    npm install web-animations-js
    
  2. Animation의 Angular .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';
  • 모듈: 각도/재료에서 MatDialogModule만 가져오면 충분합니다.가져오기 및 제공할 필요 없음:매트 대화상자 참조
  • DialogComponent가 DialogComponent인 import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material';
  • 위의 내용은 제가 수행한 단계입니다.대화 상자에서 가져와야 하는 이유를 잘 모르겠습니다.
  • 하지만 당신의 html/template에서 어떤 선택기를 사용했는지 명확히 해주시겠습니까?템플리트에 "등록 구성요소"를 사용한 경우 이 오류가 발생할 수 있습니다.재료 가이드에서 동일한 예제를 사용해 보았습니다.실수로 'dialog-overview-example' 대신 'dialog-overview-example-dialog'를 사용했습니다.저도 당신과 같은 오류가 있습니다.

component.ts 및 inspec.ts에서 가져온 경로는 동일해야 합니다.

예:

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

또는

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

저에게 문제는 단지 테스트하기 위해 다른 HTML 템플릿에 제 Dialog 구성 요소를 추가했다는 것입니다.제가 그것을 제거하자 OP의 오류가 사라지고 그냥 작동했습니다.

질문에 대한 답변은 아니지만 도움이있습니다! NullInjectorError: 테스트 파일에 MatDialogRef에 대한 공급자 없음, MatDialogData 오류가 있는 경우(.spec.ts), 그냥 추가하십시오.

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

구성 요소의 TestBed.configTestingModule에서

생성자에서 대화상자 Ref 제거:

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

위의 모든 사항 외에도 앱의 템플릿 파일 중 하나에 구성 요소 선택기에 대한 참조가 있는 경우에도 이 오류가 발생할 수 있습니다.MatDialog 구성 요소는 구성 요소 선택기를 통해가 아니라 MatDialog.dialog.open() 메서드에서만 호출해야 합니다.

안타깝게도 여러 가지 이유로 동일한 오류 메시지가 표시될 수 있습니다.

는 이오는주으로인발수있다니습생할해입류▁can▁injecting다▁be▁this있니를 주입함으로써 발생할 수 있습니다.MatDialogRefOpen 메서드로 전달되는 구성 요소가 아닌 MatDialog::open을 호출하는 구성 요소입니다.는 MatDialog 열에전구성요합같다니다아야음과기를 가져야 .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();
  }

}

저는 이 문제를 몇 번 겪었고 저의 경우 옵션 데이터가 전달된 모달을 구현하려고 했습니다.제 해결책은 표시하려는 대화 상자/모달을 구현하는 상위 모듈에 이 코드를 추가하는 것이었습니다.

이 솔루션을 테스트해 본 결과, 고객이 내부에 제공업체를 구현할 경우에 대비하여app.module.ts(조부모 등), 그리고 그것은 여전히 작동할 것입니다.

// direct.parent.module.ts

// Import statements
import{...} from '';
import{<YOUR_COMPONENT>} from 'YOUR_COMPONENT_PATH';
...

@NgModule({
  declarations: [..],
  imports:[..],
  providers: [ // <== This is the key that made it work
    {
      provide: MatDialogRef,
      useValue: {}
    },
    { provide: MAT_DIALOG_DATA, useValue: {} }, // <== I had to add this too
    <YOUR_COMPONENT> // My Component
  ],
})

export class DirectParentModule { }

분명히 제 코드에서는 모든 것이 정상이었습니다.문제는 개발하는 동안 모달 구성 요소에 대한 시간적 경로가 있어서 다른 일반 구성 요소/뷰처럼 볼 수 있다는 것입니다.구성 요소에는 모달에서 열림을 트리거하는 버튼이 있어 실제로 열렸을 때 어떻게 보이는지 테스트할 수 있습니다.

그래서 대화 상자를 여는 코드를 다른 구성 요소로 옮겼는데 문제가 해결된 것 같습니다.

이 오류는 일반적으로 필요한 모듈을 제공하지 않기 때문에 발생합니다.외부 모듈 구성 요소를 사용 중인 모듈로 외부 모듈을 가져옵니다.그것이 아마 문제를 해결할 것입니다.

내 app.module.ts에 MatDialogModule을 추가하여 문제를 해결했습니다.

import { MatDialogModule } from '@angular/material/dialog';

더미 MatDialogRef를 제공하지 마십시오. 그렇지 않으면 대화 구성 요소 내에서 더미 MatDialogRef를 사용할 수 없습니다.예를 들어, 모달 재료를 닫으려고 하면 전화를 걸 것입니다..close(){}때문에provide: MatDialogRef, useValue: {}던집니다.

모듈(위의 답변)과 가져오기를 살펴봅니다.

저의 경우, 저는 의도치 않게 수입했습니다.Dialog대신 cdk에서MatDialog물질적으로

import { Dialog } from "@angular/cdk/dialog"; // wrong
...
constructor(private dialog: Dialog) {}
import { MatDialog } from "@angular/material/dialog"; // good
...
constructor(private dialog: MatDialog) {}

언급URL : https://stackoverflow.com/questions/47270324/nullinjectorerror-no-provider-for-matdialogref

반응형