Ionic中ngFor循环内容返回页面后消失问题求助
问题原因与解决方案
我来帮你分析下这个问题,核心原因和Ionic的页面缓存机制有关:
Ionic 3默认会缓存导航过的页面,也就是说你的DashboardSettingsPage在第一次进入时会执行constructor和ngOnInit,但当你返回再重新进入时,系统会直接从缓存中取出已有的页面实例,不会再重新执行这些初始化方法。而你把Firestore的订阅逻辑放在了constructor里,虽然服务中的Observable会持续监听Firestore的变化,但缓存的页面实例可能因为视图绑定的问题,无法在再次进入时同步最新的数据(或者说第一次订阅的数据流在页面缓存期间出现了绑定失效)。
另外还有个潜在问题:你没有在页面销毁时取消订阅,这会导致内存泄漏,长期运行可能引发其他异常。
下面是两种可行的解决方案:
方案一:利用Ionic生命周期钩子处理订阅(推荐)
把订阅逻辑移到ionViewWillEnter钩子中,这个钩子会在每次页面进入成为活动页时触发(不管是第一次创建还是从缓存取出),同时在页面离开时取消订阅,避免内存泄漏:
修改DashboardSettingsPage的TS代码:
import { Settings } from './../../../models/settings'; import { DashboardSettingsService } from './../../../services/settings'; import { Component, OnDestroy } from '@angular/core'; import { IonicPage } from 'ionic-angular'; import { Subscription } from 'rxjs/Subscription'; @IonicPage() @Component({ selector: 'page-dashboard-settings', templateUrl: 'dashboard-settings.html', }) export class DashboardSettingsPage implements OnDestroy { settings: Settings[]; checkStateToggle: boolean; checkedSetting: Settings; private settingsSubscription: Subscription; // 保存订阅引用 constructor(public dashboardSettingsService: DashboardSettingsService) { } // 每次进入页面时重新订阅数据 ionViewWillEnter() { this.settingsSubscription = this.dashboardSettingsService.getSettings().subscribe(setting => { this.settings = setting; console.log(setting); }); } // 离开页面时取消订阅 ionViewWillLeave() { if (this.settingsSubscription) { this.settingsSubscription.unsubscribe(); } } // 组件销毁时确保订阅被清理 ngOnDestroy() { if (this.settingsSubscription) { this.settingsSubscription.unsubscribe(); } } onToggle(event, setting: Settings) { this.dashboardSettingsService.setBackground(setting); } }
方案二:临时禁用页面缓存(快速验证)
如果只是想快速验证问题是否由缓存导致,可以在调用navPush时禁用该页面的缓存:
// 在跳转至设置页面的代码中添加缓存禁用配置 this.navCtrl.push('DashboardSettingsPage', {}, { cache: false });
不过这个方案不推荐长期使用,因为页面缓存是Ionic提升应用性能的核心机制之一,频繁创建销毁页面会降低用户体验。
另外顺便提一下,你的服务代码里有个小bug:updateSetting方法里的checkedSetting没有加this,应该修正为:
updateSetting(setting: Settings) { this.settingDoc = this.afs.doc(`settings/${setting.id}`); this.settingDoc.update({ state: this.checkedSetting }); }
内容的提问来源于stack exchange,提问作者larin555
相关产品推荐
相关产品推荐

