typescript - Använd Angular MatDialog från en egen klass (ingår inte i app.module.ts)
Jag skulle vilja kalla på MatDialog-tjänsten från min anpassade klass som är utökad av Quills BlockEmbed. Objekt av min anpassade klass anropas av Quill-redigeraren, och klassen själv är inte registrerad någonstans. Problemet är att jag inte har någon aning om hur man injicerar MatDialog-komponenten/tjänsten på rätt sätt.
Först av min förenklade klass (custom-class.ts) ser ut så här:
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
}
Jag kan inte använda konstruktorn på något sätt :/ Quills fel. Hur som helst, som du kanske ser har jag beslutat att använda Injector-klassen, för att injicera MatDialog. Men även om objektet är skapat kan jag inte öppna dialogen ->
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)
Vid det här laget har jag ingen aning om jag använder Injector korrekt eller ens om det jag vill är möjligt. Alla förslag är välkomna :)
Svar #1
Jag fick samma problem, efter att ha kontrollerat klasserna verkar det som att injektorn inte tillhandahåller beroendeklasserna. Så, det jag har gjort för att få det att fungera är nedan:
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;
}
}
skapa service.locator.class.ts
import { MatDialog } from '@angular/material/dialog';
import { Injector } from "@angular/core";
export class ServiceLocator {
static injector: Injector;
static dialog: MatDialog;
}
Min anpassade utökade komponentklass
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);
}
}
Användningar
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);
}
}
