Angular CDK - 将自定义覆盖容器 class 注入组件创建它的新实例

Angular CDK - Injecting the Custom overlay container class into a component creates new instance of it

要求

使用自定义 OverlayContainer class 以便在特定 DOM 元素(而不是 body 上打开 Angular Material Snackbars .

此时,我知道:

我试过的代码

我在提供程序数组中提供了自定义 class。

providers: [
  {provide: OverlayContainer, useClass: AppOverlayContainer}
]

而 class 是:

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);
   }
}

在我的组件中,在打开小吃店之前,我会调用:

AppOverlayContainer.appendToCustomContainer(HTMLElement)

小吃店关门后,我会打电话给:

AppOverlayContainer.removeFromCustomContainer();

问题:

AppOverlayContainer 注入组件构造函数时,它将创建此 class 以及 OverlayContainer:

的新实例
constructor(
  private _snackBar: MatSnackBar,
  private _appOverlayContainer: AppOverlayContainer
) {}

它只有在我注入 OverlayContainer 时才起作用,然后像这样使用它:

constructor(
  private _snackBar: MatSnackBar,
  private _appOverlayContainer: OverlayContainer
) {}
(this._appOverlayContainer as AppOverlayContainer).appendToCustomContainer(appOverlayWrapperContainer);

(this._appOverlayContainer as AppOverlayContainer).removeFromCustomContainer();

这似乎有点棘手。

我真的不明白我在这里错过了什么。

Stackblitz

https://stackblitz.com/edit/angular-wksbmf-9xdxcv

您应该使用 useExisting 来避免您的服务有两个实例时出现此问题。原因是有些组件要求 OverlayContainer 而有些组件要求 AppOverlayContainer 和 angular 为每个创建的实例。将 useClass 更新为 useExisting 将有助于让 angular 仅使用一个实例:

providers: [
  {provide: OverlayContainer, useExisting: AppOverlayContainer}
]

您可以查看here了解详细信息,这将有助于在使用服务时了解不同的属性。