简体   繁体   English

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

[英]Trigger action on controller from route after model has resolved in Ember

I am fairly new to Ember, being a hardcore backbone aficionado for many years and I'm at a loss for how to handle a situation I've run into. 我对Ember并不陌生,多年来一直是骨灰级的狂热爱好者,但对于如何处理遇到的情况我一无所知。

I am using Pusher and the Pusher Ember library to build a sort of chat application. 我正在使用PusherPusher Ember库来构建某种聊天应用程序。

The way it works is, a person navigates to a users account page and it creates a new "conversation". 它的工作方式是,一个人导航到用户帐户页面,并创建一个新的“对话”。 Then, once that conversation has been created, I would like to subscribe to a pusher channel that is dynamically named after that conversations id. 然后,一旦创建了该对话,我想订阅一个以该对话ID动态命名的推送器通道。 I need to define the Pusher Subscriptions on my controller. 我需要在控制器上定义“推送程序订阅”。

Here's my route (in coffeescript) 这是我的路线(在咖啡脚本中)

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

and my controller: 和我的控制器:

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

Unfortunately, the model has not resolved at this point so I don't yet know what my @model.id is, and it fails. 不幸的是,模型在这一点上还没有解决,所以我还不知道我的@model.id是什么,它失败了。

Any advice for the best way to handle this? 对解决此问题的最佳方法有何建议?

I had the same issue when I added ember-pusher to my application. 当我在应用程序中添加ember-pusher时,我遇到了同样的问题。 The solution I went with is to define a variable in the App namespace that could be referenced. 我采用的解决方案是在App命名空间中定义一个可以引用的变量。 (Not ideal and something I'll need to fix later) (不理想,以后需要修复的问题)

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

A second, cleaner option, would be to try a needs relationship with your user controller, but I'm not sure if that will be available until after init is complete. 第二个更清洁的选择是尝试与您的用户控制器建立需求关系,但是我不确定在初始化完成后是否可以使用该关系。

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

A third option would be to lookup the user controller (singleton) during init. 第三种选择是在初始化过程中查找用户控制器(单例)。

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

UPDATE UPDATE

Since you need the conversation id you can observe when the model changes and wire up pusher the way ember-pusher/bindings.js does. 由于您需要对话ID,因此您可以观察模型何时更改,并按ember-pusher / bindings.js的方式连接推送程序。 You would no longer need to override controller.init, just set PUSHER_SUBSCRIPTIONS: {} to start with. 您将不再需要覆盖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')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM