When using Hot Module Reload and
provide(OVERLAY_CONTAINER_TOKEN, {useValue: createOverlayContainer()}),
each reload duplicates md-overlay-container overlay div
Only one overlay div
Overlay div duplicated
@zigzag95 Out of curiousity, which date picker is that? I thought the material date picker hadn't been implemented yet. Looks alot like react's material-ui datepicker.
@jimitndiaye https://github.com/zigzag95/DatePicker
@zigzag95 thanks
It's happen with me too with MdTooltip when I route from one to another route; the Overlay div duplicated many time any temp solution
I've only switched to using HMR (thank god I found it) and this issue seems to still be present.
When you leave a dialog open and edit your code, the overlay will not go away and you can't interact with your app unless:
I'm experiencing the same as @borislemke reports. I added HMR to my project and if there's a dialog open, a ghost overlay-container is added.
More importantly, the dialog loses it's bind to the styles. If you look at the <head>
section of the document, among the injected <styles>
tags you can find the specific <style>
dedicated to mat-dialog-container
. After a save (with hmr enabled), this style tag disappears. Angular "forgets" to inject the style back to the document.
To reproduce:
mat-dialog-container
element<style>…</style>
link to the right of the mat-dialog-container
class name - It'll take you to the section and focus you on the relevant <style>
tag<style>
tag in the head disappears. I hope someone can get to the bottom of this. As I work on dialogs at the moment, I have to disable HMR as it makes it impossible to save any changes without a manual reload of the page.
Before HMR reload
After HMR reload
I'm chiming in on this issue as well. I had opened a SO issue here, so far no answers. Subbed to this thread.
Please, HMR is reaaaaaaaaaaaaaaaallly necessary feature for us, EVERY DAY!
Dear Material team, Could you make HMR work properly with material 2?
This is also disrupting my team's workflow at the minute so I'm going to have a crack at creating a PR for this but for anyone else interested here's a repo that reproduces the issue https://github.com/DatacomNelson/MaterialHMR
this is a hack solution to get by for now. It removes any angular dialogs, and your app is repsonsive again. On the hmr destroy event, we nuke any dialogs that exist.
const elements = document.getElementsByClassName('cdk-overlay-container');
for (let i = 0; i < elements.length; i++) {
elements[i].innerHTML = '';
}
Then in the OnInit, we re-create all the dialogs that were open, passing in their data. The only problem is that this solution retains old dialog instances, so they are not dismiss-able from a background click. However, if the dialog has a close button wired up on it, then it will dismiss properly.
The OpenDialogs property in StateService could probably be changed to a TemplateRef
Anyway, a hack solution until official support for dialogs + hmr arrives.
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;
}
}
and 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);
Any update on this issue, it's been over two years and to be honest while the 'hack solution' suggested by seabass223 works it's quite cumbersome and should not be required.
also facing this problem, its quite annoying me, is there any update?
HMR is a nice feature, I need it!!! but with this problem... I just disabled it.
As mentioned in this isssue: Successful hot module replacement requires the components to be designed. Really hope this problem could be resolved soon.
If anyone wants to contribute a PR for this I'll be happy to take a look
@torabian dude beat it with the completely unrelated self promotion
I was trying to reproduce this with angular 7.2.5, angular cli 7.3.1 on Windows 10 and was not able to reproduce it. On each HMR reload the dialog closes and overlay div disappears from the page. I also tried steps @AsafAgranat suggested and styles did not break. Attached is the sample I have tested this. To test with my sample do the following:
This will start the application with HMR.
Are there any additional steps needed to reproduce this?
It might be fixed now if the HMR is smart enough to invoke the ngOnDestroy
of the loaded NgModules / providers.
@jelbourn what is the default setting for this to work correctly? Something like this does not work for my if a hot module reload is performed:
export class ExampleComponent implements OnInit, OnDestroy {
constructor(
private dialog: MatDialog
}
...
ngOnDestroy {
this.dialog.closeAll()
}
}
Most helpful comment
Please, HMR is reaaaaaaaaaaaaaaaallly necessary feature for us, EVERY DAY!
Dear Material team, Could you make HMR work properly with material 2?