Переход с маршрута не удаляет наблюдателей контроллера выходного маршрута в Ember.js

Вот 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 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, когда маршрут изменился, он все еще вызывается.

Любые советы, почему это может происходить, очень ценятся.


person Chris    schedule 29.11.2014    source источник


Ответы (1)


Причина, по которой опросчик продолжает работать, заключается в том, что контроллеры являются одиночками, а это означает, что контроллер будет работать в течение всего срока службы вашего приложения.

В вашем случае контроллер parent даже не трогается, потому что все, что вы делаете, это переход на другой chid маршрута parent. Но даже в том случае, если вы заменили модель контроллера parent, опросчик все равно будет работать, так как он работает на контроллере, который является одноэлементным.

Подробнее об этом можно прочитать здесь: http://balinterdi.com/2014/06/26/ember-gotcha-controllers-are-singletons.html

person tikotzky    schedule 30.11.2014