模型在Ember中解决后,从路径触发控制器上的操作

时间:2014-09-24 05:36:51

标签: javascript ruby-on-rails ember.js coffeescript

我是Ember的新手,多年来一直是铁杆骨干爱好者,我对如何处理我遇到的情况感到茫然。

我正在使用PusherPusher Ember库来构建一种聊天应用程序。

它的工作方式是,一个人导航到用户帐户页面,然后创建一个新的“对话”。然后,一旦创建了该对话,我想订阅一个在该对话id后动态命名的推送通道。我需要在我的控制器上定义Pusher订阅。

这是我的路线(在coffeescript中)

App.ConversationShowRoute = Ember.Route.extend
  model: (params) ->
    @store.createRecord('conversation', user_id: params.user_id).save()

和我的控制员:

App.ConversationShowController = Ember.ObjectController.extend
  init: ->
    subscriptions = []
    subscriptions[@model.get('id')] = ['newMessage']
    PUSHER_SUBSCRIPTIONS: subscriptions

不幸的是,此模型尚未解决,所以我还不知道我的@model.id是什么,它失败了。

有关处理此问题的最佳方法的建议吗?

1 个答案:

答案 0 :(得分:4)

当我将ember-pusher添加到我的应用程序时,我遇到了同样的问题。我使用的解决方案是在App命名空间中定义一个可以引用的变量。 (不太理想,我以后需要修理的东西)

init: function () {
  this.channelName = 'presence-document-' + App.documentId + '-channel';
  this.PUSHER_SUBSCRIPTIONS[ this.channelName ] = [
    'pusher:subscription_succeeded', 'pusher:member_added', 'pusher:member_removed',
    'client-send-status', 'client-send-message'
  ];
  this._super();
}

第二个更干净的选择是尝试与用户控制器建立需求关系,但我不确定在init完成之后它是否可用。

App.ConversationShowController = Ember.ObjectController.extend({
  needs: ['user'],
  userId: Ember.computed.alias('controllers.user.id'),

  init: function() {
    this.PUSHER_SUBSCRIPTIONS[this.get('userId')] = ['newMessage'];
    this._super(); // Maybe try putting this first if properties haven't resolved.
  }
});

第三个选项是在init期间查找用户控制器(单例)。

App.ConversationShowController = Ember.ObjectController.extend({
  init: function() {
    var userController = this.container.lookup('controller:user');
    this.PUSHER_SUBSCRIPTIONS[userController.get('id')] = ['newMessage'];
    this._super();
  }
});

<强>更新

由于您需要会话ID,您可以观察模型何时更改并按照ember-pusher / bindings.js的方式连接推送器。您不再需要覆盖controller.init,只需将PUSHER_SUBSCRIPTIONS: {}设置为开头。

afterModelLoad: function() {
    this.channelName = 'conversation-' + this.get('model.id');
    this.PUSHER_SUBSCRIPTIONS[this.channelName] = ['newMessage'];

    // From bindings.js init
    var events = this.PUSHER_SUBSCRIPTIONS[this.channelName];
    this.pusher.wire(this, this.channelName, events);

    this.removeObserver('afterModelLoad'); /* If you only want to run once */
}.observes('model')