worktile/ngx-planet

主应用和子应用同时使用angular cdk overlay时有冲突

ywager opened this issue · 4 comments

主应用和子应用同时使用了ng-zorro-antd组件库,主应用上导航使用了ng-zorro-antd下拉菜单dropdown组件,发现只要加载了子应用,主应用上导航下拉菜单点击后没反应,之前也在调研angular element开发微前端也遇到类似问题,排查后发现子应用里使用的ng-zorro-antd组件导致主应用有问题的,这些组件都使用了cdk overlay.

查看single spa微前端在使用material组件库也有类似情况,
链接: angular/components#16972
这个应该和ngx-planet没关系,想咨询下作者之前有遇到过这个问题吗?

angular version:  "@angular/core": "^8.2.14",
angular cdk version:  "@angular/cdk": "^8.1.3",
ng-zorro-antd version:   "ng-zorro-antd": "^8.5.2",

@ywager 当主应用和子应用同时使用 cdk overlay (ng-zorro-antd) 时,主应用和子应用都会实例化自己的 OverlayContainer,当其中一个应用打开过用 overlay 创建的弹框后,在销毁弹框时,_containerElement 也会从dom中移除,但是另一个应用实例的服务中 _containerElement 没有清空,导致其他应用中找不到渲染组件的节点,无法弹出弹框。

问题来源 cdk OverlayContainer 服务

getContainerElement(): HTMLElement {
    if (!this._containerElement) {
        this._createContainer();
    }
    return this._containerElement;
}

解决方案:重写 OverlayContainer 服务,实现 getContainerElement 方法,方案如下

export class StyxOverlayContainer extends OverlayContainer {
    constructor(@Inject(DOCUMENT) document: any) {
        super(document);
    }

    getContainerElement() {
        this._containerElement = this._document.getElementsByClassName('cdk-overlay-container')[0] as HTMLElement;
        if (!this._containerElement) {
            this._createContainer();
        }
        return this._containerElement;
    }
}
{
    provide: OverlayContainer,
    useClass: StyxOverlayContainer
}

@luxiaobei 多谢回复,按照上面方法初步在项目里验证了下,主应用上导航下拉菜单点击还是没反应,还不确定是哪块问题,
我写个简单的例子再看下,排除下是不是项目其它地方问题

需要在每一个子应用和主应用中重写 OverlayContainer 服务

@luxiaobei 是在主应用和每个子应用写的,我再看下