从路由转换不会删除 Ember.js 中退出路由的控制器观察器

Transitioning from a route doesn't remove exited route's controller observers in Ember.js

本文关键字:路由 退出 控制器 观察 Ember 转换 删除 js      更新时间:2023-09-26

这里有一个JSBin来说明我遇到的问题。

http://jsbin.com/patuje/4

我正在使用依赖注入来对 API 进行轮询机制,如下所示

App.Poller = Ember.Object.extend({
  interval: function() {
    return 1000;
  }.property().readOnly(),
  schedule: function(f) {
    return Ember.run.later(this, function() {
      f.apply(this);
      this.set('timer', this.schedule(f));
    }, this.get('interval'));
  },
  stop: function() {
    this.set('running', false);
    Ember.run.cancel(this.get('timer'));
  },
  start: function() {
    if (!this.get('running')) {
      this.set('running', true);
      this.set('timer', this.schedule(this.get('onPoll')));
    }
  },
  onPoll: function() {
    Ember.Logger.log('basic poller overwrite with your method');
  }
});
App.register('poller:main', App.Poller);
App.inject('route', 'poller', 'poller:main');
App.inject('controller', 'poller', 'poller:main');

这样我就可以从我的路由和控制器调用开始和停止轮询。

我设置了父路由,以便它间歇性地轮询服务器以获取父路由中的进度,如下所示(请注意,获取语法来自 Ember Data beta 12,但工作正常(

App.ParentRoute = Ember.Route.extend({
  setupController: function(controller, model) {
    store = this.store;   
    controller.set('model', model);
    this.poller.reopen({
      onPoll: function() {
        return store.fetch('mymodel', 1);
      }
    });  
  },
  model: function() {
    return this.store.find('mymodel', 1);
  }
});

作为步骤过程的一部分,我有各种子路由,这取决于从 API 轮询接收的数据,因此在子控制器中,我设置了一个这样的观察者

App.ParentChild1Controller = Ember.Controller.extend({
  needs: ['parent'],
  progress: Ember.computed.alias('controllers.parent.progress'),
  pollingChild1: function() {
    progress = this.get('progress');
    Ember.Logger.log('called from pollingChild1 : ', progress);
    if (progress < 50) {
      this.poller.start();
    } else {
      this.transitionToRoute('parent.child2');
    }
  }.observes('progress').on('init')
});

它只是开始轮询,一旦进度超过 50,就会过渡到下一个路由。

我不明白的是,为什么在过渡到新路线后,这个观察者继续被称为?

如果在路由更改时从该 JSBin 查看控制台,它仍在被调用。

非常感谢为什么

会发生这种情况的任何建议。

轮询器继续运行的原因是控制器是单例,这意味着控制器将在应用程序的生命周期内保留。

在您的情况下,甚至没有触及parent控制器,因为您所做的只是过渡到parent路线的另一个 chid。但是,即使您交换了parent控制器的模型,轮询器仍将运行,因为它在单例控制器上运行。

您可以在此处阅读有关它的更多信息:http://balinterdi.com/2014/06/26/ember-gotcha-controllers-are-singletons.html