在ShadowDOM中使用CDK覆盖容器

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

我正在尝试在 Web 组件内使用 Angular Material 组件。除了 cdk-overlays 的一种边缘情况外,一切正常。到目前为止,我已经成功地使用 _createContainer() 的重写将覆盖容器附加到 Shadowroot 内部的 div 中,以便应用样式。但是,如果我使用 *ngIf 隐藏父元素,然后将其切换回来,覆盖容器会出现在 DOM 中,但它及其包含的元素不可见。

我是否缺少某些内容,需要手动清除或切换某些内容才能使该行为正常工作?

代码基于此答案:将 MatDialog 弹出窗口添加到 Angular Root 而不是主体

@Injectable({ providedIn: "root" })
export class AppOverlayContainer extends OverlayContainer implements OnDestroy {
  constructor(@Inject(DOCUMENT) _document: any) {
    super(_document);
  }

  ngOnDestroy() {
    super.ngOnDestroy();
  }

  getRootElement(): Element {
    return this._document
      .querySelector("web-component-tag")
      .shadowRoot.querySelector("#angular-app-root");
  }

  createContainer(): void {
    this._createContainer();
  }

  protected _createContainer(): void {
    super._createContainer();
    this._appendToRootComponent();
  }

  private _appendToRootComponent(): void {
    if (!this._containerElement) {
     return;
    }
    const rootElement = this.getRootElement();
    const parent = rootElement || this._document.body;
    parent.appendChild(this._containerElement);
  }
}

HTML

<ng-container *ngIf="toggleWidget$ | async">


<app-conversations
    id="angular-app-root"
    [toggleWidget$]="toggleWidget$"
    [contextTitle]="contexttitle"
    [contexts]="contexts"
    [preloadConversations]="subscribeonload"
    [widgetIdentifier]="uniqueId"
  ></app-conversations>
</ng-container>
<ng-container
  *ngIf="(toggleWidget$ | async) === false && !overridelaunchbutton"
>
  <button
    mat-fab
    class="message-button"
    color="primary"
    (click)="toggleWidget$.next(true)"
  >
    <mat-icon svgIcon="message"></mat-icon>
    <div class="unread-pip" *ngIf="hasUnreadMessages">
      {{ unreadMessageCount }}
    </div>
  </button>
</ng-container>
<ng-container *ngIf="overridelaunchbutton">
  <button
    mat-icon-button
    [ngClass]="launchbuttonclass"
    [color]="launchbuttoncolor"
    (click)="toggleWidget$.next(true)"
  >
    <mat-icon svgIcon="{{ launchbuttonicon }}"></mat-icon>
    <div class="unread-pip" *ngIf="hasUnreadMessages">
      {{ unreadMessageCount }}
    </div>
  </button>
</ng-container>
angular angular-material web-component
2个回答
1
投票

除了覆盖容器被 *ngIf 包装时会发生奇怪的行为之外,我从未找到过这个问题的根源。当 *ngIf 第一次显示、切换为不可见然后再次显示时,会导致容器内呈现的内容出现问题。将其移到 *ngIf 之外解决了我的情况下的问题。


0
投票

此行为的原因是您继承的基类型。即使整个 Web 组件被销毁,它仍然会保留您在

_createContainer
中创建的缓存元素。

有 2 个修复

  1. 要么自己实现整个类而不继承
    OverlayContainer
  2. 或者在基类内部覆盖
    getContainerElement
    ,如下所示
    override getContainerElement(): HTMLElement {
      if (!this._containerElement || !this._containerElement.isConnected) {
        this._createContainer();
      }
    
      return this._containerElement;
    }
    
© www.soinside.com 2019 - 2024. All rights reserved.