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);
}
나는 이 오류를 가지고 있었고 그것을 수정했습니다 당신이 해야 하는 것입니다.
다음과 같이 형식 스크립트 파일에 가져오기 문을 삽입했는지 확인합니다.
"@angular/material/dialog"에서 {MAT_DIALOG_DATA, MatDialogRef} 가져오기;
생성자를 확인합니다.
constructor(@Optional() public dialogRef: MatDialogRef<GadgetAuthMessagesComponent>, @Inject(MAT_DIALOG_DATA) public message: string){ }
이제 모듈 .ts로 이동하여 가져오기를 확인합니다.
import {MAT_DIALOG_DATA, MatDialogModule, MatDialogRef} from '@angular/material/dialog';
module.ts에서 가져오기 배열 아래에 MatDialogModule 이름을 넣어야 합니다.
매트 대화 모듈
이제 마침내 그것이 완료되었습니다. 우리는 공급자 배열을 업데이트해야 합니다.
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를 지원합니다.
어쨌든 폴리필을 얻으려면 다음 단계를 수행해야 합니다.
터미널에서 콘솔에 다음을 입력합니다.
npm install web-animations-js
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있니를 주입함으로써 발생할 수 있습니다.MatDialogRef
Open 메서드로 전달되는 구성 요소가 아닌 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
'programing' 카테고리의 다른 글
파일이나 어셈블리 'mssshrtmi' 또는 해당 종속성 중 하나(Azure Table Storage Access)를 로드할 수 없습니다. (0) | 2023.04.26 |
---|---|
Eclipse 하위 버전 프로젝트 연결 복원 (0) | 2023.04.26 |
C#에서 2 List를 병합하고 중복된 값을 제거하는 방법 (0) | 2023.04.26 |
한 파일에서 다른 파일에 있는 줄 삭제 (0) | 2023.04.21 |
프로세스가 완료될 때까지 기다립니다. (0) | 2023.04.21 |