Angular Mat-Select路由返回后无选项显示及报错问题
Angular mat-select 路由返回后下拉菜单失效问题
问题详情
我有一个mat-select多选下拉组件,代码如下:
<mat-form-field appearance="outline"> <mat-select multiple> <mat-option value="Option1">Option 1</mat-option> <mat-option value="Option2">Option 2</mat-option> </mat-select> </mat-form-field>
首次进入NetworkComponent时组件运行正常,但导航到其他页面(如http://localhost:7005/#/pages/chat)再返回后,下拉菜单不再显示选项,同时抛出以下错误:
首次点击报错
ERROR TypeError: Cannot read properties of null (reading 'appendChild') at NbOverlayContainerAdapter._createContainer (index.js:952:1) at NbOverlayContainerAdapter.getContainerElement (overlay.js:714:1) at Overlay._createHostElement (overlay.js:2606:1) at Overlay.create (overlay.js:2573:1) at CdkConnectedOverlay._createOverlay (overlay.js:2810:1) at CdkConnectedOverlay._attachOverlay (overlay.js:2884:1) at CdkConnectedOverlay.ngOnChanges (overlay.js:2802:1) at checkAndUpdateDirectiveInline (core.js:21760:1) at checkAndUpdateNodeInline (core.js:30689:1) at checkAndUpdateNode (core.js:30651:1)
后续点击报错
ERROR TypeError: Cannot read properties of undefined (reading 'updateSize') at CdkConnectedOverlay.ngOnChanges (overlay.js:2791:1) at checkAndUpdateDirectiveInline (core.js:21760:1) at checkAndUpdateNodeInline (core.js:30689:1) at checkAndUpdateNode (core.js:30651:1) at prodCheckAndUpdateNode (core.js:31193:1) at Object.updateDirectives (index.d.ts.MatSelect.html:17:1) at Object.updateDirectives (core.js:30978:1) at checkAndUpdateView (core.js:30633:1) at callViewAction (core.js:30874:1) at execComponentViewsAction (core.js:30816:1)
NetworkComponent代码:
import { Component } from '@angular/core'; @Component({ selector: 'app-network', templateUrl: './network.component.html', styleUrls: ['./network.component.scss'], }) export class NetworkComponent {}
解决方法
从报错栈可以看出,问题根源是NbOverlayContainerAdapter无法正确创建或获取Overlay容器,导致mat-select的下拉面板无法渲染。以下是几种可行的修复方案:
手动初始化Overlay容器
在组件初始化时,主动触发Overlay容器的创建逻辑,确保路由返回后容器存在:import { Component, OnInit } from '@angular/core'; import { NbOverlayContainer } from '@nebular/theme'; @Component({ selector: 'app-network', templateUrl: './network.component.html', styleUrls: ['./network.component.scss'], }) export class NetworkComponent implements OnInit { constructor(private overlayContainer: NbOverlayContainer) {} ngOnInit(): void { // 强制获取容器,触发创建逻辑 this.overlayContainer.getContainerElement(); } }清理Overlay资源(路由复用场景)
如果项目使用了路由复用策略,组件实例未被销毁可能导致Overlay资源残留。在组件销毁时清理Overlay实例:import { Component, OnDestroy } from '@angular/core'; import { Overlay } from '@angular/cdk/overlay'; @Component({ selector: 'app-network', templateUrl: './network.component.html', styleUrls: ['./network.component.scss'], }) export class NetworkComponent implements OnDestroy { constructor(private overlay: Overlay) {} ngOnDestroy(): void { // 销毁所有关联的Overlay实例 this.overlay.dispose(); } }版本兼容性检查与升级
该问题可能是Nebular与Angular CDK版本不匹配导致的已知bug。核对@nebular/theme和@angular/cdk的版本兼容性,升级到对应Angular主版本的稳定Nebular版本。替换为Angular原生OverlayContainer
若Nebular的OverlayContainer存在问题,尝试使用Angular原生容器确保稳定性:import { Component, OnInit } from '@angular/core'; import { OverlayContainer } from '@angular/cdk/overlay'; @Component({ selector: 'app-network', templateUrl: './network.component.html', styleUrls: ['./network.component.scss'], }) export class NetworkComponent implements OnInit { constructor(private overlayContainer: OverlayContainer) {} ngOnInit(): void { const container = this.overlayContainer.getContainerElement(); // 确保容器已挂载到DOM if (!document.body.contains(container)) { document.body.appendChild(container); } } }
内容的提问来源于stack exchange,提问作者CoolMathematician
相关产品推荐
相关产品推荐

