我一直在为此苦苦挣扎,目前找到了一个不太理想的解决方案。在 hmr 销毁事件期间,它会从 DOM 中删除任何有角度的对话框。
const elements = document.getElementsByClassName('cdk-overlay-container');
for (let i = 0; i < elements.length; i++) {
elements[i].innerHTML = '';
}
然后在 OnInit 中,我们重新创建所有打开的对话框,并传入它们的数据。唯一的问题是这个解决方案保留了旧的对话框实例,所以它们不能从背景点击中解散。但是,如果对话框上连接了一个关闭按钮,那么它将正确关闭。
StateService 中的 OpenDialogs 属性可能会更改为包含 componentInstances 的 TemplateRef[],这可能会解决问题,但我不确定。
无论如何,在对 dialogs + hmr 的官方支持到来之前,一个 hack 解决方案。
app.module.ts
export class AppModule {
constructor(private state: StateService, public dialog: MatDialog) { }
OnInit(store) {
if (store !== undefined) {
this.state.SetState(store.State);
for (let i = 0; i < this.state.OpenDialogs.length; i++) {
const t = this.state.OpenDialogs[i].componentInstance;
this.dialog.open(t.constructor, { data: t.data });
}
}
}
OnDestroy(store) {
this.state.OpenDialogs = this.dialog.openDialogs;
store.State = this.state;
const elements = document.getElementsByClassName('cdk-overlay-container');
for (let i = 0; i < elements.length; i++) {
elements[i].innerHTML = '';
}
}
}
state.service.ts:
import { Injectable } from '@angular/core';
import { MatDialogRef } from '@angular/material';
@Injectable({
providedIn: 'root'
})
export class StateService {
public OpenDialogs: MatDialogRef<any>[];
constructor() {
}
public SetState(_state: StateService) {
this.OpenDialogs = _state.OpenDialogs;
}
}
main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
// tslint:disable-next-line:no-shadowed-variable
function bootstrap(AppModule) {
return platformBrowserDynamic().bootstrapModule(AppModule)
.then(moduleRef => {
if (environment.hmr) {
if (module['hot']) {
module['hot']['accept']();
if (moduleRef.instance['OnInit']) {
if (module['hot']['data']) {
moduleRef.instance['OnInit'](module['hot']['data']);
}
}
if (moduleRef.instance['OnStatus']) {
module['hot']['apply']((status) => {
moduleRef.instance['OnStatus'](status);
});
}
if (moduleRef.instance['OnCheck']) {
module['hot']['check']((err, outdatedModules) => {
moduleRef.instance['OnCheck'](err, outdatedModules);
});
}
if (moduleRef.instance['OnDecline']) {
module['hot']['decline']((dependencies) => {
moduleRef.instance['OnDecline'](dependencies);
});
}
module['hot']['dispose'](store => {
if (moduleRef.instance['OnDestroy']) {
moduleRef.instance['OnDestroy'](store);
}
moduleRef.destroy();
if (moduleRef.instance['AfterDestroy']) {
moduleRef.instance['AfterDestroy'](store);
}
});
}
}
return moduleRef;
});
}
bootstrap(AppModule);