Angular - 在父容器内打开底部工作表 (MatBottomSheet)

ET-*_*-CS 7 angular-material bottom-sheet angular

我正在尝试打开 div 容器内的材质底部表,默认情况下它作为主体内的最后一个元素打开。

查看文档,我需要使用viewContainerRef,但我无法使其工作。

这与我想做的类似:

应用程序组件.html:

...
<div #container></div>
...
Run Code Online (Sandbox Code Playgroud)

应用程序组件.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,
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

但似乎并没有做出任何改变。

任何帮助,将不胜感激。

提前致谢

and*_*tor 2

似乎对viewContainerRef选项的真正含义存在误解。

MatBottomsheetComponentPortal. 从ComponentPortal 文档中,我们可以找到更详细的描述viewContainerRef

附加组件应该位于 Angular 的逻辑组件树中。

这与组件渲染的地方不同,

这是由 PortalOutlet 决定的。当主机位于 Angular 应用程序上下文之外时,原点是必需的。

打开底页时检查 DOM 时,我们会发现以下组件层次结构:

  1. OverlayContainer-<div class="cdk-overlay-container"></div>
  2. Overlay-<div id="cdk-overlay-{id}" class="cdk-overlay-pane">
  3. ComponentPortal-<bottom-sheet-container></bottom-sheet-container>
  4. 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;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

但不幸的是,它是一个单例并产生了一个新问题:

MatBottomSheetMatDialogMatSnackbarMatTooltip组件使用相同的 OverlayContainer,因此所有这些组件都将在此自定义容器中打开。