Ionic 2中定时器回调报错:TypeError: Cannot read property 'viewCtrl' of undefined
解决Ionic 2中定时器回调报错
Cannot read property 'viewCtrl' of undefined的问题 嗨,这个报错的根源很明确:你把页面的endTimer函数传给Provider时,函数的上下文(也就是this的指向)丢失了,再加上你代码里用了未定义的self,直接导致找不到viewCtrl和navCtrl。下面给你两种快速修复的方法,还有额外的优化建议:
修复方案一:用箭头函数保留上下文
在调用Provider的newTimer方法时,用箭头函数包裹你的endTimer调用,这样就能确保this还是指向当前页面组件:
newTimer() { // 用箭头函数包裹,保留组件的this上下文 this.countDown = this.timerProvider.newTimer(() => this.endTimer()); } endTimer() { // 直接用this即可,不用未定义的self const indexModal = this.viewCtrl.index; this.navCtrl.push(WinnersPage, { gameId: this.gameId }).then(() => { // 这里可以补充移除导航栈的逻辑,比如 this.navCtrl.remove(indexModal); }); console.log('timer ENDED'); }
修复方案二:提前绑定this到函数
在页面组件的构造函数里,把endTimer的this绑定到当前组件,这样不管怎么传递函数,上下文都不会丢:
constructor( public viewCtrl: ViewController, public navCtrl: NavController, public timerProvider: TimerProvider ) { // 绑定this到endTimer,确保上下文不丢失 this.endTimer = this.endTimer.bind(this); } newTimer() { this.countDown = this.timerProvider.newTimer(this.endTimer); } endTimer() { const indexModal = this.viewCtrl.index; this.navCtrl.push(WinnersPage, { gameId: this.gameId }).then(() => {}); console.log('timer ENDED'); }
额外优化建议
- 防止内存泄漏:页面销毁时记得取消定时器订阅,避免内存占用:
import { OnDestroy } from '@angular/core'; import { Subscription } from 'rxjs'; // 让页面组件实现OnDestroy接口 export class YourPage implements OnDestroy { countDown: Subscription; ngOnDestroy() { if (this.countDown) { this.countDown.unsubscribe(); } } }
- 避免全局变量冲突:你Provider里的
counter是全局变量,如果多个页面同时调用定时器,会互相干扰。建议改成每个定时器独立的变量,比如把counter作为参数传入:
// Provider里的newTimer方法修改 newTimer(endTimer, counter = 100) { // 默认倒计时100秒 let currentCounter = counter; return Observable.timer(0, this.tick) .take(currentCounter) .map(() => --currentCounter) .finally(() => endTimer()); } // 页面调用时可以自定义倒计时时长 this.countDown = this.timerProvider.newTimer(() => this.endTimer(), 60); // 60秒倒计时
内容的提问来源于stack exchange,提问作者astrakid932
相关产品推荐
相关产品推荐

