简体   繁体   English

从路线过渡不会删除Ember.js中退出的路线的控制器观察者

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

Here is a JSBin to illustrate the problem I have. 这是一个JSBin来说明我遇到的问题。

http://jsbin.com/patuje/4 http://jsbin.com/patuje/4

I'm using a dependency injection to make a polling mechanism to an API, something like this 我正在使用依赖项注入对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');

So that I can call start and stop polling from my routes & controllers. 这样我就可以从路由和控制器调用开始和停止轮询。

I set up the parent route so that it intermittently polls the server for progress in the parent route like this (note the fetch syntax is from Ember Data beta 12 but works fine) 我设置了父路由,以使其间歇性地轮询服务器以获取父路由的进度,如下所示(请注意,获取语法来自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);
  }
});

I have various child routes as part of a step process which depends on the data received from the API polling, so in a child controller I set up an observer like this 作为分步过程的一部分,我有各种子路线,这取决于从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')
});

It simply starts the polling and once the progress is above 50 transitions to the next route. 它只是开始轮询,并且一旦进度超过50,便转换到下一条路线。

What I don't understand is why after transitioning to the new route this observer continues to be called? 我不明白的是,为什么在过渡到新路线后仍继续调用该观察者?

If you look at the console from that JSBin when the route has changed it is still being called. 如果您在更改路由后从该JSBin查看控制台,则仍在调用它。

Any advice why this might be happening is very much appreciated. 非常感谢任何为什么会发生这种情况的建议。

The reason why the poller continues to run is because controllers are singletons which means that the controller will stick around for the lifetime of your application. 轮询程序继续运行的原因是控制器是单例的,这意味着控制器将在应用程序的整个生命周期内始终存在。

In your case the parent controller is not even touched because all you are doing is transitioning to another chid of the parent route. 在您的情况下,甚至没有触摸parent控制器,因为您正在做的只是过渡到parent路由的另一个控件。 But even in the case that you swapped out the model of the parent controller, the poller would still be running since its running on the controller which is a singleton. 但是即使交换了parent控制器的模型,轮询器仍将在运行,因为它在单例控制器上运行。

You can read more about it here: http://balinterdi.com/2014/06/26/ember-gotcha-controllers-are-singletons.html 您可以在此处了解更多信息: http : //balinterdi.com/2014/06/26/ember-gotcha-controllers-are-singletons.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM