将MatDialog弹出窗口添加到Angular Root而不是Body

问题描述 投票:0回答:1

我制作了一个Angular 6应用,其中有一些MatDialog。这在开发模式下完美工作。

现在,我必须将其实现到现有网站(使用sitecore 9)中。这很好用,只是对话框无法正确打开。我发现对话框被添加到主体而不是我的有角根DOM元素。

<html>
  <head></head>
  <body>
    <app-library>...</app-library>

    <div class="cdk-overlay-container">...</div>
  </body>
</html>

是否可以将对话框添加到有角度的app元素(在我的情况下)而不是body元素?

我已经尝试使用viewContainerRef选项matDialog,但这似乎不起作用:

export class AppComponent implements OnInit {
  constructor(..., public viewRef: ViewContainerRef) {
}

export class FilterToggleComponent implements OnInit {
  constructor(..., public dialog: MatDialog, private appRef: ApplicationRef) {}
  openFilterPanel() {
    const viewRef = (this.appRef.components[0].instance as AppComponent).viewRef;
    const dialogRef = this.dialog.open(FilterPanelComponent, {
      width: '100vw',
      height: '100%',
      panelClass: 'search-filter-panel-modal',
      viewContainerRef: viewRef
    });
  }
}
angular angular-material2
1个回答
0
投票

根据角材料docsviewContainerRefMatDialogConfig选项为:

附加的组件应该位于Angular的逻辑组件树中。这会影响可用于注入的内容以及在对话框内部实例化的组件的更改检测顺序。

这不会影响对话框内容的呈现位置。

[在打开对话框时检查DOM时,我们将找到以下组件层次结构:

  1. [Body-<body>
  2. [OverlayContainer-<div class="cdk-overlay-container"></div>
  3. [Overlay-<div id="cdk-overlay-{id}" class="cdk-overlay-pane">
  4. [ComponentPortal-<mat-dialog-container></mat-dialog-container>
  5. Component-我们的ComponentExampleDialog组件,其打开方式为:this.dialog.open(ComponentExampleDialog)

现在,我们真正需要更改的是OverlayContainer在DOM中的位置,根据docs,它是:]]

容器元素,其中所有单个叠加层元素都位于呈现。

默认情况下,覆盖容器直接附加到文档主体。

从技术上讲,可以提供custom

覆盖容器,如documentation中所述,但不幸的是,它是singleton,并产生了潜在的问题:

[MatDialogMatSnackbarMatTooltipMatBottomSheet和所有使用OverlayContainer的组件将在此自定义容器中打开。

如果这不是问题,请使用以下代码,该代码使用id="angular-app-root"将覆盖容器附加到元素:

@NgModule({
  providers: [{provide: OverlayContainer, useClass: AppOverlayContainer}],
 // ...
})
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('#angular-app-root');
    if (element !== null) {
      element.appendChild(container);
      this._containerElement = container;
    }
  }
}

然后,添加以下CSS:

.app-overlay-container {
  position: absolute;
  z-index: 1000;
  pointer-events: none;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
}

.app-overlay-container:empty {
  display: none;
}

Stackblitz演示:https://stackblitz.com/edit/angular-wksbmf

此外,以下文章可能会有用,因为它包含类似的实现:https://blog.bbogdanov.net/post/angular-material-overlay-hack-overlay-container/

© www.soinside.com 2019 - 2024. All rights reserved.