Requirement
Use a custom OverlayContainer class in order to open Angular Material Snackbars on a specific DOM element (not on body).
At this point, I know that:
- the
OverlayContainerclass is a singleton - I want to display only the snackbars on a specific DOM element and let the Dialogs, Tooltips and the other Material elements use the default overlay container element that is appended to
body.
The code I've tried
I provided the custom class in the providers array.
providers: [
{provide: OverlayContainer, useClass: AppOverlayContainer}
]
And the class is:
export class AppOverlayContainer extends OverlayContainer {
/**
* Append the OverlayContainer to the custom element
*/
public appendToCustomContainer(element: HTMLElement): void {
// this._containerElement is 'cdk-overlay-container'
element.appendChild(this._containerElement);
}
**
* Remove the OverlayContainer from the custom element and append it to body
*/
public removeFromCustomContainer(): void {
this._document.body.appendChild(this._containerElement);
}
}
In my component, before opening a snackbar, I will call:
AppOverlayContainer.appendToCustomContainer(HTMLElement)
And after the snackbar closes, I will call:
AppOverlayContainer.removeFromCustomContainer();
The issue:
When injecting the AppOverlayContainer into the component constructor, it will create a new instance of this class and also of the OverlayContainer:
constructor(
private _snackBar: MatSnackBar,
private _appOverlayContainer: AppOverlayContainer
) {}
It works only if I inject the OverlayContainer, then use it like:
constructor(
private _snackBar: MatSnackBar,
private _appOverlayContainer: OverlayContainer
) {}
(this._appOverlayContainer as AppOverlayContainer).appendToCustomContainer(appOverlayWrapperContainer);
(this._appOverlayContainer as AppOverlayContainer).removeFromCustomContainer();
Which seems kind of tricky.
I really don't understand what I am missing here.
Stackblitz