【问题标题】:Angular - Open Bottom Sheet (MatBottomSheet) inside parent containerAngular - 在父容器内打开底部表 (MatBottomSheet)
【发布时间】: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)

标签: angular angular-material bottom-sheet


【解决方案1】:

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

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

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

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 2018-03-11
    • 1970-01-01
    • 1970-01-01
    • 2022-11-27
    • 2023-03-19
    • 2021-10-25
    相关资源
    最近更新 更多