Angular切换状态后@ViewChild获取swiperRef为undefined,如何重置该变量?
解决Angular里swiperRef切回SCHEDULE后变undefined的问题
为啥会出这问题?
当stateName不是SCHEDULE时,*ngIf会直接把<swiper-container>从DOM里删掉,对应的swiperRef自然就成了undefined。切回SCHEDULE时,元素会重新生成,但有时候Angular的变更检测没及时跟上,或者你在元素还没重建好的时候就去拿引用,就会拿到undefined。
怎么解决?
1. 先确认@ViewChild的配置没问题
确保你的@ViewChild用的是默认的static: false(Angular 8之后默认就是这个),这样它会在视图更新后自动刷新引用:
@ViewChild('swiper') public swiperRef: ElementRef | undefined;
2. 监听swiper元素的变化
用ViewChildren代替ViewChild,监听元素列表的变化,这样元素重建时能第一时间拿到新引用:
import { ViewChildren, QueryList, ElementRef, AfterViewInit } from '@angular/core'; @ViewChildren('swiper') swiperRefs!: QueryList<ElementRef>; ngAfterViewInit() { this.swiperRefs.changes.subscribe(() => { this.swiperRef = this.swiperRefs.first; if (this.swiperRef) { // 这里可以重新初始化swiper或者做你需要的操作 // 比如拿到swiper实例:const swiper = this.swiperRef.nativeElement.swiper; } }); }
3. 换个方式切换显示(不想销毁元素的话)
要是不想让swiper元素被销毁,只是隐藏,可以用ng-container搭配ng-template,或者用[hidden](不过[hidden]元素还是会渲染,只是看不见,性能上不如*ngIf):
<ng-container *ngIf="stateName == 'SCHEDULE'; else otherState"> <swiper-container #swiper [pagination]="true"> ... </swiper-container> </ng-container> <ng-template #otherState> <!-- 其他状态的内容 --> </ng-template>
4. 手动触发变更检测(实在不行再用)
如果上面的方法都不管用,可能是变更检测没跑起来,可以手动调一下:
import { ChangeDetectorRef } from '@angular/core'; constructor(private cdr: ChangeDetectorRef) {} // 比如在stateName切换的方法里调用 switchToSchedule() { this.stateName = 'SCHEDULE'; this.cdr.detectChanges(); // 现在再拿swiperRef应该就有值了 if (this.swiperRef) { // 做你要的操作 } }
内容的提问来源于stack exchange,提问作者quma
相关产品推荐
相关产品推荐

