【问题标题】:Angular Material Dialog & Hot Module Reload角度材料对话框和热模块重新加载
【发布时间】:2018-05-17 01:29:16
【问题描述】:

到目前为止,我已经成功完成了以下工作:

✓ HMR(热模块重新加载)设置
✓ 角度 (5) 和材料工作良好
✓ 打开一个对话框(代码如下 sn-p)

// ...
constructor(private dialog: MatDialog){}
//...
public openDialog(){
    this.dialogRef = this.dialog.open(someDialogComponent, {
      width: '300px'
    });
}

✓ 对对话框或对话框的父控制器进行更改
✓ HMR 被触发(耶)
✖ 对话框挂在死状态,由于对话框和背景被“卡住”且无法点击,页面基本上被冻结

我尝试在父或对话框控制器中连接ngOnInitngOnDestroy 以关闭对话框引用(如果存在),我也尝试过dialog.closeAll(),但这没有奏效。此外,理想情况下对话框不必关闭,但我似乎无法修复这个僵尸对话框问题。

有人遇到过吗?

【问题讨论】:

  • 我今天遇到了这个确切的问题,因为我正在我的项目中实现 hmr。这很奇怪。在没有打开对话框的情况下更新样式完美无缺。但是一旦打开对话框,任何需要重新编译(更改组件样式、html 或 ts)的文件保存都会导致 Material Dialog 失去它与 Material Dialog 样式的绑定,这实际上会导致它卡在屏幕上。跨度>
  • 找到这个讨论它的reported issue

标签: angular angular-material2 webpack-hmr


【解决方案1】:

我一直在为此苦苦挣扎,目前找到了一个不太理想的解决方案。在 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;
  }
}

ma​​in.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);

【讨论】:

  • 有人找到更新,还是我们还需要解决方法?
  • 同样的解决方法适用于 Primeng 对话框。 @TimHarker 相应的 github 问题已被 bot 关闭。显然十几个人是不够大的人群。 github.com/angular/angular-cli/issues/9600
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
  • 2020-09-05
  • 2018-06-17
  • 1970-01-01
  • 2020-04-24
相关资源
最近更新 更多