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

Posted

技术标签:

【中文标题】Angular - 在父容器内打开底部表 (MatBottomSheet)【英文标题】:Angular - Open Bottom Sheet (MatBottomSheet) inside parent container 【发布时间】:2019-09-13 10:31:19 【问题描述】:

我正在尝试在 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,
        );
    

但它似乎没有任何改变。

任何帮助将不胜感激。

提前致谢

【问题讨论】:

我似乎遇到了同样的问题。看来 ViewContainerRef 没有做任何事情。我正在使用最新的 Angular 版本 (8.x.x) 【参考方案1】:

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

MatBottomsheet 是用ComponentPortal 创建的。从ComponentPortaldocumentation可以找到viewContainerRef更详细的描述:

附加组件应该位于 Angular 的 logical 组件树中的位置。

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

由 PortalOutlet 决定。当宿主在 Angular 应用程序上下文之外时,源是必需的。

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

    OverlayContainer - &lt;div class="cdk-overlay-container"&gt;&lt;/div&gt; Overlay - &lt;div id="cdk-overlay-id" class="cdk-overlay-pane"&gt; ComponentPortal - &lt;bottom-sheet-container&gt;&lt;/bottom-sheet-container&gt; 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;
    
  

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

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

【讨论】:

以上是关于Angular - 在父容器内打开底部表 (MatBottomSheet)的主要内容,如果未能解决你的问题,请参考以下文章

Angular - 如何将整个垫脚行移动到表格顶部

在 mat-table 的 mat-cell 内实现 if else 条件 - Angular 5

Angular Material - Mat-Dialog - 改变背景模糊/变暗效果

将弹性项目保留在父容器内

更新子组件内的道具,使其也在父容器上更新

Angular Material 2:多个 mat-table 排序仅适用于第一个表