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

App.SearchController = Ember.ObjectController.extend({
    needs: ['navigation'],

    updateResults: function () {
        console.log('load search data');
    }.observes('controllers.navigation.search')
});

Полный образец

http://jsfiddle.net/FMk7R/1/

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

Как я могу определить, какой контроллер в данный момент активен, и загрузить данные только в активный?

1
mr_eko 18 Фев 2013 в 23:16

1 ответ

Лучший ответ

В идеале ваши контроллеры не должны знать, что они активны. Одна альтернатива - инвертировать отношение, чтобы NavController отвечал за изменение свойства запроса «активного» контроллера.

** ОБНОВЛЕНИЕ - добавление примера на основе комментария **

App.SearchRoute = Ember.Route.extend({
  setupController: function(controller) {
      this.controllerFor('navigation').set('active', controller);
  }
});

App.ImagesRoute = Ember.Route.extend({
  setupController: function(controller) {
      this.controllerFor('navigation').set('active', controller);
  }
});

App.SearchController = Ember.ObjectController.extend({
  loadResults: function (query) {
    console.log('loading web search data for: ', query);
  }
});

App.ImagesController = Ember.ObjectController.extend({
  loadResults: function (query) {
    console.log('loading image search data for: ', query);
  }
});

App.NavigationController = Ember.ObjectController.extend({
  search: '',
  active: null,
  searchDidChange: function() {
    this.get('active').loadResults(this.get('search'));
  }.observes('search', 'active')
});

См. http://jsfiddle.net/F3uFp/1/.

Другой альтернативой является использование вместо этого вычисляемых свойств. Ember обновит только вычисленные свойства, которые действительно необходимы для рендеринга активного представления. Например:

    App.SearchController = Ember.ObjectController.extend({
        needs: ['navigation'],
        results: function () {
           console.log('loading web search data');
           return("web search results");
        }.property('controllers.navigation.search')
    });

См. Обновленную скрипку здесь: http://jsfiddle.net/ZTnmp/

http://jsfiddle.net/FMk7R/1/

3
Mike Grassotti 19 Фев 2013 в 00:38
Вы упомянули, что я могу перевернуть отношения, как я могу это сделать? Я имею в виду, как я могу получить активный контроллер в NavigationController?
 – 
mr_eko
19 Фев 2013 в 00:10
needs: ['active'] в NavigationController, а затем у вас есть controllers.active.
 – 
Wildhoney
19 Фев 2013 в 00:12
Определите свойство (скажем, «active») на NavigationController, которое устанавливается из обработчика setupController на SearchRoute и ImagesRoute, например: this.controllerFor('navigation').set('active', controller); - тогда вы можете наблюдать изменения в поле поиска из NavigationController и вызовите соответствующие методы на любом активном контроллере.
 – 
Mike Grassotti
19 Фев 2013 в 00:32
needs: ['active'] у меня не работал. Я пробовал это: jsfiddle.net/ZTnmp/2
 – 
mr_eko
19 Фев 2013 в 00:42
Не знаю, почему я всегда думал, что setupController запускается только один раз при запуске. Кажется немного странным, что это не поддерживается чем-то похожим на то, что описал @Wildhoney ... Я имею в виду, чтобы вы могли знать, что в настоящее время загружено.
 – 
mr_eko
19 Фев 2013 в 00:45