使用自定义类中的 Angular MatDialog(不包含在 app.module.ts 中)

lem*_*mek 5 typescript quill angular-material angular

我想从由 Quills BlockEmbed 扩展的自定义类调用 MatDialog 服务。我的自定义类的对象由 Quill 编辑器调用,并且类本身未在任何地方注册。问题是我不知道如何正确注入 MatDialog 组件/服务。

我的第一个简化类 (custom-class.ts) 如下所示:

import { Injector } from '@angular/core';
import { MatDialog } from '@angular/material';
import { DialogContentComponent } from '../dialog-content-component/dialog-content-component';
import Quill from 'quill';

const BlockEmbed = Quill.import('blots/block/embed');

export class AssideBlot extends BlockEmbed {
    static blotName = 'eAside';
    static tagName = 'element-article';
    static className = 'aside-articles';

    static create(articleIdArray: any) {
        // some quills stuff
        const injector = Injector.create({ providers: [{ provide: MatDialog, deps: [] }] });
        const dialog: MatDialog = injector.get(MatDialog);

        const dialogRef = this.dialog.open(DialogContentComponent, {
            data: {},
            height: 'auto',
            maxWidth: '100vw',
            width: '600px',
            panelClass: 'mat-dialog-no-gutter'
          });

          dialogRef.afterClosed().subscribe(result => {
            // some logic
          });
        // More logic
    }
    // More quills stuff
}
Run Code Online (Sandbox Code Playgroud)

我不能以任何方式使用构造函数:/ Quills 错误。不管怎样,正如你可能看到的,我决定使用 Injector 类来注入 MatDialog。但是,即使创建了对象,我也无法打开对话框 ->

ERROR TypeError: Cannot read property 'position' of undefined
    at MatDialog.push../node_modules/@angular/material/esm5/dialog.es5.js.MatDialog._getOverlayConfig (dialog.es5.js:946)
    at MatDialog.push../node_modules/@angular/material/esm5/dialog.es5.js.MatDialog._createOverlay (dialog.es5.js:923)
    at MatDialog.push../node_modules/@angular/material/esm5/dialog.es5.js.MatDialog.open (dialog.es5.js:846)
    at HTMLButtonElement.<anonymous> (AsideArticleBlot.ts:36)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
    at Object.onInvokeTask (core.js:17290)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
    at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:498)
    at invokeTask (zone.js:1744)
    at HTMLButtonElement.globalZoneAwareCallback (zone.js:1781)
Run Code Online (Sandbox Code Playgroud)

在这一点上,我不知道我是否正确使用了 Injector,或者即使我想要的是可能的。欢迎任何建议:)

小智 2

我遇到了同样的问题,在检查类后,注入器似乎没有提供依赖项类。因此,为了使其发挥作用,我所做的工作如下:

export class AppModule {
  constructor(public dialog: MatDialog) {
    ServiceLocator.injector = Injector.create({
      providers:
        Object.keys(services).map(key => ({
          provide: services[key].provide,
          useClass: services[key].provide,
          deps: services[key].deps
        }))
    }
    );
    ServiceLocator.dialog = dialog;
  }
}
Run Code Online (Sandbox Code Playgroud)

创建service.locator.class.ts

import { MatDialog } from '@angular/material/dialog';
import { Injector } from "@angular/core";

export class ServiceLocator {
    static injector: Injector;
    static dialog: MatDialog;
}
Run Code Online (Sandbox Code Playgroud)

我的自定义扩展组件类

import { MatDialog } from "@angular/material/dialog";
import { ServiceLocator } from "../services/service.locator.class";

export class ExtendedComponent {
    protected dialog: MatDialog;

    constructor() {
        this.dialog = ServiceLocator.dialog;
    }

    /**
     * Shows given component into popup modal
     *
     * @protected
     * @param {*} modelComponent
     * @memberof ExtendedComponent
     */
    protected OpenDialog(modelComponent: any): void {
        this.dialog.open(modelComponent);
    }
}
Run Code Online (Sandbox Code Playgroud)

用法

import { Component, OnInit } from '@angular/core';
import { ExtendedComponent } from '../../shared/extended.component';
import { AboutUsComponent } from '../about-us/about-us.component';

@Component({
  selector: 'app-menu-bar',
  templateUrl: './menu-bar.component.html',
  styleUrls: ['./menu-bar.component.less']
})
export class MenuBarComponent extends ExtendedComponent implements OnInit {

  constructor() {
    super();
  }

  ngOnInit(): void {
  }

  /**
   * Show about us dialog
   *
   * @memberof MenuBarComponent
   */
  ShowAboutUs(): void {
    this.OpenDialog(AboutUsComponent);
  }

}
Run Code Online (Sandbox Code Playgroud)