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
.
此时,我知道:
OverlayContainer
class是单例
- 我想在特定 DOM 元素 上仅显示 快餐栏,并让对话框、工具提示和其他 Material 元素使用默认覆盖附加到
body
. 的容器元素
我试过的代码
我在提供程序数组中提供了自定义 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
您应该使用 useExisting
来避免您的服务有两个实例时出现此问题。原因是有些组件要求 OverlayContainer
而有些组件要求 AppOverlayContainer
和 angular 为每个创建的实例。将 useClass
更新为 useExisting
将有助于让 angular 仅使用一个实例:
providers: [
{provide: OverlayContainer, useExisting: AppOverlayContainer}
]
您可以查看here了解详细信息,这将有助于在使用服务时了解不同的属性。
要求
使用自定义 OverlayContainer
class 以便在特定 DOM 元素(而不是 body
上打开 Angular Material Snackbars
.
此时,我知道:
OverlayContainer
class是单例- 我想在特定 DOM 元素 上仅显示 快餐栏,并让对话框、工具提示和其他 Material 元素使用默认覆盖附加到
body
. 的容器元素
我试过的代码
我在提供程序数组中提供了自定义 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
您应该使用 useExisting
来避免您的服务有两个实例时出现此问题。原因是有些组件要求 OverlayContainer
而有些组件要求 AppOverlayContainer
和 angular 为每个创建的实例。将 useClass
更新为 useExisting
将有助于让 angular 仅使用一个实例:
providers: [
{provide: OverlayContainer, useExisting: AppOverlayContainer}
]
您可以查看here了解详细信息,这将有助于在使用服务时了解不同的属性。