gpt4 book ai didi

angular - 将 MatDialog 弹出窗口添加到 Angular Root 而不是 body

转载 作者:行者123 更新时间:2023-12-04 13:20:59 25 4
gpt4 key购买 nike

我制作了一个 Angular 6 应用程序,其中有一些 MatDialog。这在开发模式下非常有效。

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

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

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

有没有办法将对话框添加到 Angular 应用程序元素(在我的例子中)而不是主体元素?

我已经尝试过使用 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 Material docs , viewContainerRef MatDialogConfig 的选项是:

Where the attached component should live in Angular's logical component tree. This affects what is available for injection and the change detection order for the component instantiated inside of the dialog.

This does not affect where the dialog content will be rendered.

在打开对话框时检查 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 , 是:

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

By default, the overlay container is appended directly to the document body.

从技术上讲,可以提供自定义 覆盖容器,如documentation 中所述。 , 但不幸的是,它是一个单例 并且会产生一个潜在的问题:

MatDialog , MatSnackbar , MatTooltip , MatBottomSheet以及所有使用 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/

关于angular - 将 MatDialog 弹出窗口添加到 Angular Root 而不是 body,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52763285/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com