【问题标题】:MAT_DIALOG_DATA: Error: inject() must be called from an injection context Error: inject() must be called from an injection contextMAT_DIALOG_DATA:错误:必须从注入上下文调用注入()错误:必须从注入上下文调用注入()
【发布时间】:2020-01-22 17:57:04
【问题描述】:

我从教程中制作了一个基本的模式对话框,有点卡住了,加载我的项目给我带来了这个错误:

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 injection() 而不是大写-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();
  }
}

所有类似的帮助主题都说要确保我使用的是大写字母-I @Inject 而不是我正在做的注入。但是,我确实看到了从“@angular/core/testing”而不是“@angular/core”导入 Inject 的建议,我认为这是不可能的?

任何帮助都将不胜感激,我以前从来没有在 Hello World 项目上被卡住这么多次。

新:

好的,我认为我已经满足了所有 5 个要求,但我仍然看到同样的错误。 这是我的 app.module.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 { }

我的 term.component 文件应该启动术语对话框

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

【问题讨论】:

  • 尝试从两个组件文件中删除 NgModule 并且不要忘记删除与其相关的所有导入(只是为了节省一些空间 - 虽然不是关键)
  • 我看到您没有传递任何数据,您也可以在 TermDialog 中删除声明 Inject 。这不是强制性的。
  • 所以这些只是表面上的改变,对吧?如何解决“从注入上下文注入”问题?
  • 我认为它与 TermDialog 组件中的选择器和 templateURL 有关系。让我确认需要进行哪些更改。

标签: angularjs angular-material


【解决方案1】:

要使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定义中声明组件为entryComponents

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

解决方案

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

如果您还没有这样做,您可能还想添加 animations 模块。

参考:MatDialog not showing

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

参考:Angular Material's Dialog won't display correctly

【讨论】:

  • 好的,所以我认为我已经满足了所有 5 个要求(我将 dialogcomponent 添加到 entryComponents 数组中),但我仍然看到同样的错误。编辑原件以包含我的 term.component 类和我的 app.module 文件
  • @BrandonMiller 一切看起来都很好,除了两个组件上的 NgModule。无论如何,您都是在 app.module 中导入包,因此您可以从两个组件中删除该部分。
  • 我仍然看到相同的行为。
  • 让我在最后运行它。请在 30 分钟后回来查看。
  • TermDialog 没有单独的 HTML。它指的是 TermComponent 的模板和选择器..
【解决方案2】:

好吧,原来答案是根本不使用 MatDialogs,只需使用 TermDialogComponent 的选择器标记将 TermDialogComponent html 注入到基本模式对话框中

所以我将模态对话框的 html 添加到我的 term.component.html 中并简单地粘贴到

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

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

感谢大家的回复和时间

【讨论】:

    【解决方案3】:

    TermDialog 没有单独的 HTML。它指的是 TermComponent 的模板和选择器。

    Live Demo

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

    动画 还要将BrowserAnimationsModule 添加到app.module

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

    参考:MatDialog not showing

    主题 我猜你也处理了材料主题。

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

    参考: Angular Material's Dialog won't display correctly

    【讨论】:

      猜你喜欢
      • 2021-08-07
      • 2019-08-15
      • 1970-01-01
      • 1970-01-01
      • 2018-12-31
      • 2021-11-26
      • 2020-08-05
      • 2022-06-16
      • 2020-08-25
      相关资源
      最近更新 更多