【问题标题】:TypeError: Cannot read property 'viewCtrl' of undefined in Ionic 2TypeError:无法读取 Ionic 2 中未定义的属性“viewCtrl”
【发布时间】:2018-05-22 06:25:57
【问题描述】:

我在从特定页面调用的提供程序中有一个Observable.timer。我还将一个函数传递给提供者 Observable,当它完成倒计时时,它将调用位于初始页面中的函数。但定时器结束后我得到错误:

注意:我在页面中导入了视图控制器,但没有在提供程序中导入(如果我尝试在提供程序中导入视图控制器,则会出现另一个错误)

错误

退订期间发生1个错误:↵ 1)TypeError:无法读取 未定义的属性'viewCtrl'

页面

  newTimer() {
    this.countDown = this.timerProvider.newTimer(this.endTimer); //pass function below
  }

  endTimer() {

    const indexModal = self.viewCtrl.index;
    // then we remove it from the navigation stack
    //this.navCtrl.remove(2);

    self.navCtrl.push(WinnersPage, {
      gameId: self.gameId
    }).then(() => {

    });

    console.log('timer ENDED');
  }

提供者

  countDown: any;
  counter = 1*100;
  tick = 1000;

  constructor(public http: HttpClient) {
    //console.log('Hello TimerProvider Provider');
  }

  newTimer(endTimer) {
     return Observable.timer(0, this.tick)
      .take(this.counter).map(() => --this.counter)
      .finally(() => endTimer());
  }

【问题讨论】:

  • 使用endTimer.bind(this)后还是一样的错误吗?
  • 我不能使用 this.endTimer.bind(this) 因为当用户离开初始页面时绑定会导致函数在提供程序内部触发,我在提供程序内部实现计时器的主要原因是用户可以返回导航堆栈,计时器暂停或继续。如果用户使用 .bind() 离开页面,则会触发 endTimer()。具有自我全局变量的另一个解决方案似乎不错,但仍然出现错误......知道如何让它工作吗?
  • bind() 不执行该功能。它所做的只是 return 一个绑定到提供的上下文的新函数。我什至不确定您要做什么。但是您帖子中的错误应该使用绑定功能解决。您遇到的任何其他问题可能是由于您的代码中的其他登录存在问题。
  • *逻辑未登录。

标签: angular ionic-framework ionic2


【解决方案1】:

简单易用,

  newTimer() {
    this.countDown = this.timerProvider.newTimer(this.endTimer.bind(this)); 
  }

或者:

由于您从another function 调用function,因此this 的引用在endTimer funciton

中不可用

因此,将component this 分配给global variable self 并在endTimer function 中使用它

试试这个,

 let self = this;

  newTimer() {
    this.countDown = this.timerProvider.newTimer(this.endTimer); //pass function below
  }

  endTimer() {

    const indexModal = self.viewCtrl.index;
    if(self.answerModal) {
      self.answerModal.dismiss();
    }
    if(self.hintModal) {
      self.hintModal.dismiss();
    }
    self.navCtrl.push(WinnersPage, {
      gameId: self.gameId
    }).then(() => {

    });

    self.storage.set('firstAnswerCreated', '');
    self.playaudio.pause();

    console.log('timer ENDED');
  }

【讨论】:

  • 使用this.endTimer.bind(this)更容易
  • @PaulSamsotha,thnx,我想到了,但不知道,如果我可以使用它,thnx 的建议。我更新了答案
  • 如果我使用第一个选项:(this.endTimer(this)),endTimer() 函数会在没有计时器的页面加载时立即调用。如果我使用第二个选项,我会得到同样的错误
  • @condo1234,你能粘贴完整的组件吗?
  • @Sravan 刚刚添加
猜你喜欢
  • 1970-01-01
  • 2017-10-07
  • 2015-03-28
  • 1970-01-01
  • 1970-01-01
  • 2017-06-24
  • 1970-01-01
  • 2017-11-06
  • 1970-01-01
相关资源
最近更新 更多