我正在尝试在div容器中打开材料底页,默认情况下,它是作为主体内的最后一个元素打开的。
看着documentation,我需要使用viewContainerRef
,但是我无法使其正常工作。
这与我正在尝试做的事情类似:
app.component.html:
...
<div #container></div>
...
app.component.ts:
export class AppComponent implements AfterViewInit {
@ViewChild('container', { read: ViewContainerRef }) _container;
...
constructor(
private bottomSheet: MatBottomSheet,
) {}
ngAfterViewInit() {
this.bottomSheet.open(MySheetComponent, {
panelClass: 'my-modal',
viewContainerRef: this._container,
});
}
}
但是它似乎没有任何改变。
任何帮助将不胜感激。
预先感谢
答案 0 :(得分:0)
似乎对viewContainerRef
选项的真正含义有误解。
MatBottomsheet
是使用ComponentPortal
创建的。从ComponentPortal
documentation,我们可以找到对viewContainerRef
的更详细的描述:
附加组件应位于Angular的逻辑组件树中的位置。
这与组件呈现的位置不同
由PortalOutlet确定。当主机位于Angular应用程序上下文之外时,源是必需的。
在打开底表时检查DOM时,我们将找到以下组件层次结构:
OverlayContainer
-<div class="cdk-overlay-container"></div>
Overlay
-<div id="cdk-overlay-{id}" class="cdk-overlay-pane">
ComponentPortal
-<bottom-sheet-container></bottom-sheet-container>
Component
-我们的BottomSheet
。现在,我们真正需要更改的是OverlayContainer
,根据docs,它是:
所有单个叠加层元素都位于其中的容器元素 呈现。
默认情况下,覆盖容器直接附加到文档主体。
从技术上讲,可以提供一个自定义覆盖容器:
@NgModule({
providers: [{provide: OverlayContainer, useClass: CustomOverlayContainer}],
// ...
})
export class MyModule { }
export class AppOverlayContainer extends OverlayContainer {
protected _createContainer(): void {
const container: HTMLDivElement = document.createElement('div');
container.classList.add('app-overlay-container');
const element: Element | null = document.querySelector('#custom-overlay-contaier');
if (element !== null) {
element.appendChild(container);
this._containerElement = container;
}
}
}
但是,不幸的是,它是一个 singleton ,并产生了一个新问题:
MatBottomSheet
,MatDialog
,MatSnackbar
,MatTooltip
组件使用相同的OverlayContainer,因此所有这些组件都将在此自定义容器中打开。