【问题标题】:Trigger action on controller from route after model has resolved in Ember在 Ember 中解析模型后,从路由触发控制器动作
【发布时间】:2014-11-18 11:59:20
【问题描述】:

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

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

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

这是我的路线(在咖啡脚本中)

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 是什么,所以它失败了。

对于处理这个问题的最佳方法有什么建议吗?

【问题讨论】:

  • 我注意到你没有从模型返回任何东西,你试过return @store.createRecord('conversation', user_id: params.user_id).save() 吗?
  • @Hrishi 我相信 coffeescript 它默认返回函数的最后一行。无论如何,我试过了,没有骰子。我相信 init 在控制器第一次实例化时被调用,但记录保存的承诺尚未返回,因此没有 id。

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


【解决方案1】:

当我将 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();
}

第二种更简洁的选择是尝试与您的用户控制器建立需求关系,但我不确定在初始化完成之前是否可用。

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.
  }
});

第三种选择是在初始化期间查找用户控制器(单例)。

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')

【讨论】:

  • 这是非常有用的。不幸的是,我认为它不会继续工作,因为我没有使用 userId 作为频道名称,而是使用 conversationId,它是在您导航到对话页面时创建的,所以我无法知道它是什么,直到进入页面。
  • 我刚刚更新了我的答案,包括一个模型观察者,一旦模型加载,您就可以在其中连接。
  • 太棒了@jheth!观察者!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多