Как вызвать событие для 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

So now to the big question: is there a better way to access the router or a controller from outside Ember? Preferably send an event to either with a context.

Да. Это звучит как хорошая подгонка для инструментального модуля 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 . Используйте обратный вызов before для регистрации события и отправки его полезной нагрузки на контроллер.

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 здесь: Ссылка

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

    
ответ дан 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 учитывал угасание

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