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

标签 angular typescript angular-material quill

我想从由 Quills BlockEmbed 扩展的自定义类调用 MatDialog 服务。我的自定义类的对象由 Quill 编辑器调用,并且类本身未在任何地方注册。问题是我不知道如何正确注入(inject) 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
}

我不能以任何方式使用构造函数:/Quills 错误。不管怎样,正如你可能看到的,我决定使用 Injector 类来注入(inject) 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)

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

最佳答案

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

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;
  }
}
创建 service.locator.class.ts
import { MatDialog } from '@angular/material/dialog';
import { Injector } from "@angular/core";

export class ServiceLocator {
    static injector: Injector;
    static dialog: MatDialog;
}
我的自定义扩展组件类
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);
    }
}
用法
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);
  }

}

关于angular - 使用自定义类中的 Angular MatDialog(不包含在 app.module.ts 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56578046/

相关文章:

typescript - 在不同文件夹中为我自己的代码定义 Typescript 类型

javascript - TypeScript:尝试访问 Enum 时没有参数类型为 'string' 的索引签名

angular - 选择用户 ID 后显示 JSON 用户数组中的数据

javascript - Angular2 xlink :href Issues

javascript - NavigationEnd 的 url 属性返回未定义(Angular 6)

css - 如何在 Angular 5 中隐藏所选选项标签中的某些字符?

Angular Nested Drag and Drop/CDK Material cdkDropListGroup cdkDropList 嵌套

javascript - 以编程方式设置选定值 - Mat Select Angular

Angular:在一个组件中调用一个函数,在另一个组件上调用事件

angular - 如何在不丢失准备好的 css 的情况下在 Ionic 2/3 中编写自定义组件?