Angular-父容器内的打开底表(MatBottomSheet) [英] Angular - Open Bottom Sheet (MatBottomSheet) inside parent container

查看:310
本文介绍了Angular-父容器内的打开底表(MatBottomSheet)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在div容器中打开材料底页,默认情况下,它是作为主体内的最后一个元素打开的.

I'm trying to open a material bottom sheet inside a div container, as default it's opening as the last element inside the body.

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

Looking at the documentation, I need to use the viewContainerRef, but I can't make it work.

这与我正在尝试做的事情类似:

This is similiar to what I'm trying to do:

app.component.html:

app.component.html:

...
<div #container></div>
...

app.component.ts:

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,
        });
    }
}

但这似乎没有任何改变.

But it doesn't seems to make any change.

任何帮助将不胜感激.

预先感谢

推荐答案

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

It seems that there is a misunderstanding of what viewContainerRef option really means.

MatBottomsheet 是使用 ComponentPortal 创建的.从 ComponentPortal 文档中,我们可以找到更多内容 viewContainerRef 的详细说明:

The MatBottomsheet is created with ComponentPortal. From ComponentPortal documentation, we can found a more detailed description of viewContainerRef:

附加组件应位于Angular的逻辑组件树中的位置.

由PortalOutlet确定.当主机位于Angular应用程序上下文之外时,源是必需的.

which is determined by the PortalOutlet. The origin is necessary when the host is outside of the Angular application context.

在打开底表时检查DOM时,我们将找到以下组件层次结构:

When inspecting the DOM when a bottomsheet is opened, we'll find the following component hierarchy:

  1. OverlayContainer -< div class ="cdk-overlay-container"></div>
  2. 重叠 -< div id ="cdk-overlay- {id}" class ="cdk-overlay-pane">
  3. ComponentPortal -< bottom-sheet-container></bottom-sheet-container>
  4. Component -我们的 BottomSheet .
  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 - our BottomSheet.

现在,我们真正需要更改的是 OverlayContainer ,根据

Now, what we really need to change is the OverlayContainer, which, according to docs, is:

所有单独的叠加元素都位于其中的容器元素呈现.

the container element in which all individual overlay elements are rendered.

从技术上讲,可以提供一个自定义覆盖容器:

Technically it is possible to provide a custom overlay container:

@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 ,并产生了一个新问题:

but, unfortunately, it is a singleton and creates a new problem:

MatBottomSheet MatDialog MatSnackbar MatTooltip 组件使用相同的OverlayContainer,因此所有这些组件都将打开在此自定义容器中.

MatBottomSheet, MatDialog, MatSnackbar, MatTooltip components use the same OverlayContainer, so all these components will open within this custom container.

这篇关于Angular-父容器内的打开底表(MatBottomSheet)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆