Как запустить событие в Ember из другой структуры

17

Мы используем версию pre4 ember.

У нас есть структура (SignalR), работающая параллельно с ember, которая обрабатывает уведомления в реальном времени для нашего приложения. В старых версиях ember мы смогли получить доступ к глобальной ссылке маршрутизатора / контроллера. Но с новой версией Ember это уже невозможно. (Это отлично) Мы пробовали разные подходы, такие как настройка глобального контроллера на верхнем маршруте:

setupController: function(){
    app.appController = this.controllerFor('app');
}

и отправки события этому контроллеру, который пузырится до маршрута следующим образом:

notificator.update = function (context) { 
    app.appController.send('notificationOccured', context);
});

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

Итак, теперь к большому вопросу: есть ли лучший способ доступа к маршрутизатору или контроллеру со стороны Ember? Предпочтительно отправлять событие либо с контекстом.

Вся помощь приветствуется!

    
задан TommyKey 22.01.2013 в 13:12
источник

2 ответа

36
  

Итак, теперь к большому вопросу: есть ли лучший способ доступа к маршрутизатору или контроллеру со стороны Ember? Предпочтительно отправлять событие либо с контекстом.

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

Сначала добавьте метод ApplicationController для обработки обновлений. Если здесь не определено, событие будет пузыриться на маршрутизаторе.

App.ApplicationController = Ember.Controller.extend({
  count: 0,
  name: 'default',
  signalrNotificationOccured: function(context) {
    this.incrementProperty('count');
    this.set('name', context.name);
  }
});

Затем настройте свой ApplicationController, подписавшись на событие signalr.notificationOccured . Используйте перед обратным вызовом для регистрации события и отправки его полезной нагрузки в контроллер.

App.ApplicationRoute = Ember.Route.extend({
  setupController: function (controller, model) {
    Ember.Instrumentation.subscribe("signalr.notificationOccured", {
      before: function(name, timestamp, payload) {
        console.log('Recieved ', name, ' at ' + timestamp + ' with payload: ', payload);
        controller.send('signalrNotificationOccured', payload);
      },
      after: function() {}
    });
  }
});

Затем из приложения SignalR используйте Ember.Instrumentation.instrument для отправки полезной нагрузки в ApplicationController следующим образом:

notificator.update = function (context) { 
  Ember.Instrumentation.instrument("signalr.notificationOccured", context);
});

Я разместил рабочую копию с симулированными уведомлениями SignalR здесь: Ссылка

Документы на инструментальном модуле можно найти здесь , также проверьте спехи для получения дополнительных примеров.

    
ответ дан Mike Grassotti 24.01.2013 в 19:34
источник
  • инструмент как имя для отправки сигнала довольно смущает, на мой взгляд. Что означает «Инструмент блок кода с помощью Ember.instrument означает точно: отправить сигнал с указанным именем и полезной нагрузкой и вызвать обратный вызов в конце? Кстати хорошая уловка. –  ken 25.01.2013 в 06:33
  • Сладкий, это было прекрасно! Этот дизайн оправдывает то, что я искал. Работает как шарм. –  TommyKey 25.01.2013 в 10:16
  • Майк, это может быть только то, что я ищу, но может ли это быть использовано для событий общего назначения или только для рендеринга? Это только пузырь вверх или может любой объект прослушивать событие, вызванное любым другим объектом? В идеале мне бы хотелось дублировать jQuery $ .trigger (), который позволяет настраивать события на заказ в любом месте и запускать их из любого места. –  commadelimited 12.03.2013 в 15:39
  • Он может использоваться для событий общего назначения, не уверен, что вы подразумеваете под пузырем вверх, но аппаратура не относится к рендерингу. Конечно, любой объект может прослушивать события, вызванные любым другим объектом. –  Mike Grassotti 12.03.2013 в 20:02
  • Мне нравится этот подход, но он нуждается в дополнительной работе, если вы хотите использовать его в более переходном контроллере (т. е. не ApplicationController). В этом случае нам необходимо позаботиться о том, чтобы отменить подписку, или мы будем доставлять события уже уничтоженным контроллерам. В нашем приложении мы закончили подписку на активацию hook и отмену подписки на деактивировать hook. –  Damir Zekić 14.04.2013 в 12:50
Показать остальные комментарии
3

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

APP.__container__.lookup('controller:foo').get('content');
APP.__container__.lookup('view:foo').get('templateName');
APP.__container__.lookup('router:main');

Я думаю, что вам следует сделать инкапсуляцию вызовов в стороннюю библиотеку внутри Ember и позволить Ember управлять всем приложением. См. эту попытку , чтобы сделать JQuery UI ember-aware

    
ответ дан ken 23.01.2013 в 21:32
источник
  • Е. Мы подумали об использовании контейнера, но я думаю, что это @wycats, который переименовал его в контейнер из контейнера, чтобы разработчик «действительно» понимал, что не использовать его :) Итак, теперь я останусь без контейнера , Но я посмотрю на попытку JQuery-UI-Ember. Thanx для ссылки! –  TommyKey 24.01.2013 в 08:40
  • Это работает для моих целей, спасибо. Есть ли другой способ сделать это, когда можно избежать использования контейнера? –  Jake Rowsell 16.02.2015 в 11:07