MAT_DIALOG_DATA:错误:必须从注入上下文调用 inject() 错误:必须从注入上下文调用 inject(



我已经从教程中制作了一个基本的模态对话框,但有点卡住了,加载我的项目会给我这个错误:

ERROR Error: Uncaught (in promise): Error: inject() must be called from an injection context
Error: inject() must be called from an injection context
at injectInjectorOnly (core.js:728)

我不确定为什么错误消息说小写 i inject(( 而不是大写 I @Inject,我在构造函数中调用

import { Component, NgModule, OnInit } from '@angular/core';
import { Inject } from '@angular/core';
import { MatDialog, MatDialogRef, MatDialogConfig, MatDialogModule, MAT_DIALOG_DATA } from '@angular/material/dialog';
@Component({
selector: 'term-component',
templateUrl: './term.component.html'
})
@NgModule({
imports: [MatDialog, MatDialogRef, MatDialogConfig, MatDialogModule],
providers: [{
provide: MatDialog, useValue: {}
}]
})
export class TermDialog implements OnInit {
constructor(
@Inject(MAT_DIALOG_DATA) private modalData: any,
public dialogRef: MatDialogRef<TermDialog>
) {
console.log(this.modalData);
}
ngOnInit() { alert(''); }
actionFunction() {
this.closeModal();
}
closeModal() {
this.dialogRef.close();
}
onNoClick(): void {
this.dialogRef.close();
}
}

所有类似的帮助主题都说要确保我正在使用大写的 @Inject 而不是我正在做的注入。但是,我确实看到了一个建议,即从"@angular/核心/测试"而不是"@angular/核心"导入 Inject,我认为这是不可能的?

任何帮助将不胜感激,我以前从未在Hello World项目中遇到过这么多次。

新增功能:

好的,所以我认为我已经满足了所有 5 个要求,但我仍然看到相同的错误。 这是我的应用程序.模块.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { RouterModule } from '@angular/router';
import { OverlayModule } from '@angular/cdk/overlay';
import { MatDialogModule } from '@angular/material/dialog';
import { AmplifyAngularModule, AmplifyService } from 'aws-amplify-angular';
import { AppComponent } from './app.component';
import { NavMenuComponent } from './nav-menu/nav-menu.component';
import { HomeComponent } from './home/home.component';
import { CounterComponent } from './counter/counter.component';
import { FetchDataComponent } from './fetch-data/fetch-data.component';
import { TermComponent } from './term.component';
import { TermDialog } from './term-dialog.component';
import { LoginComponent } from './login/login.component';
@NgModule({
declarations: [
AppComponent,
NavMenuComponent,
HomeComponent,
CounterComponent,
FetchDataComponent,
TermComponent,
LoginComponent,
TermDialog
],
imports: [
AmplifyAngularModule,
BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
HttpClientModule,
FormsModule,
OverlayModule,
MatDialogModule,
RouterModule.forRoot([
{ path: '', redirectTo: '/login', pathMatch: 'full' },
{ path: 'login', component: LoginComponent },
{ path: 'counter', component: CounterComponent },
{ path: 'fetch-data', component: FetchDataComponent },
{ path: 'term', component: TermComponent },
{ path: '**', component: LoginComponent }
])
],
entryComponents: [
TermDialog
],
providers: [
AmplifyService
],
bootstrap: [AppComponent]
})
export class AppModule { }

和我的术语.组件文件,应该启动术语对话框

import { Component, NgModule } from '@angular/core';
import { MatDialog, MatDialogConfig, MatDialogModule, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { TermService } from '../../services/term.service';
import { TermDialog } from './term-dialog.component';
import { compileNgModule } from '@angular/compiler';
@Component({
selector: 'term-component',
templateUrl: './term.component.html'
})
@NgModule({
imports: [MatDialogModule],
providers: [{ provide: MatDialog, useValue: {} 
}]
})
export class TermComponent {
clicked: boolean;
success: boolean;
constructor(public dialog: MatDialog, private termService: TermService) {
this.clicked = false;
}
openAddNewTermDialog() {
const dialogConfig = new MatDialogConfig();
dialogConfig.disableClose = true;
dialogConfig.height = "350px";
dialogConfig.width = "600px";
dialogConfig.data = {
};
const dialogRef = this.dialog.open(TermDialog, dialogConfig);
dialogRef.afterClosed().subscribe(result => {
console.log('closed dialog');
this.success = result;
})
}
}

为了使mat-dialog按预期工作,我们必须满足以下几点。

# 1在其对应的module中声明dialog组件。

@NgModule({
imports: [
// ...
MatDialogModule
],
declarations: [
AppComponent,
ExampleDialogComponent
],
entryComponents: [
ExampleDialogComponent
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}

# 2使用父组件中MatDialog类型的变量调用mat-dialog

public dialog: MatDialog

# 3在对话框组件上声明dialogRef以访问其方法。

@Component({/* ... */})
export class YourDialog {
constructor(public dialogRef: MatDialogRef<YourDialog>) { }
closeDialog() {
this.dialogRef.close('Pizza!');
}
}

# 4如果要将一些数据从父组件传递到对话框组件,请在对话框组件上声明@Inject

import {Component, Inject} from '@angular/core';
import {MAT_DIALOG_DATA} from '@angular/material/dialog';
@Component({
selector: 'your-dialog',
template: 'passed in {{ data.name }}',
})
export class YourDialog {
constructor(@Inject(MAT_DIALOG_DATA) public data: any) { }
}

# 5module定义中将组件声明为入口组件。

参考 - https://medium.com/@ppm1988/matdialog-not-displaying-properly-b3c4cf19ec4

解决方案

我看到你已经处理了第3点和第4点。也尝试修复其他点。

您可能还想添加animations模块(如果尚未这样做(。

参考: 未显示 MatDialog

确保应用程序加载了css主题。

参考:角度材质的对话框无法正确显示

好吧,事实证明答案只是根本不使用 MatDialogs,只需使用 TermDialogComponent 的选择器标签将 TermDialogComponent html 注入基本模式对话框

所以我在我的术语.component中添加了模态对话框的html.html并简单地粘贴到

<term-dialog-component></term-dialog-component>

一切都按预期工作,没有任何大惊小怪,添加了任何模块/库。我可能永远不知道为什么我无法让基本的模态 MatDialog 正常工作,但我已经对此感到平静。我对任何有同样问题的人的建议是不要使用 MatDialogs,这不值得,而且奇怪的选项卡动画看起来很有趣。

感谢大家的回复和时间

TermDialog没有单独的HTML。它指的是术语组件的模板和选择器。

现场演示

我已经注释掉了演示代码中与解决方案无关的一些语句。

动画还向应用程序模块添加BrowserAnimationsModule

import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
@NgModule({
// ...
imports: [BrowserAnimationsModule],
// ...
})

参考: 未显示 MatDialog

主题我想你也照顾了材料主题

<link href="https://unpkg.com/@angular/material/core/theming/prebuilt/indigo-pink.css" rel="stylesheet">

裁判: 角度材质的对话框无法正确显示

最新更新