检测Ember.js应用程序中的路径/视图转换

时间:2013-08-16 00:03:38

标签: ember.js

我的应用程序的路由器看起来像这样(它是CoffeeScript):

App.Router.map () ->
  @resource 'conversations', { path: '/' } ->
    @resource 'conversation', { path: ':conversation_id' }
    @route 'new'

因此,在我的应用中,我有/new/1/2等路径。

我想检测从/1/2的转换,以便在我的视图中进行一些初始化(基本上,将焦点放在textarea字段上)。不幸的是,由于/1/2使用相同的路线,似乎几乎不可能检测到这种转变。

我尝试在视图中使用didInsertElement(如here所述)或在控制器中观察currentPath(如here所述)。如果我从/new转到/1(不同的路线),它会正常工作,但如果我从/1转到/2则不行。

我发现this gist建议使用StateManager,但它似乎过时了(我不确定它是否真的是我需要的。)

你建议我做什么?

修改

似乎每次调用setupController所以我决定像这样重载:

App.ConversationRoute = Ember.Route.extend {

  setupController: (controller, model) ->
    controller.set 'model', model
    # do something here?

}

我希望在我的视图中调用init方法:

App.ConversationView = Ember.View.extend {

  init: ->
    @$('form textarea').focus()

}

但是我仍然无法弄清楚如何让这两件事情一起工作(这是一个问题,因为我读到控制器不应该知道视图)。

感谢您的帮助!

3 个答案:

答案 0 :(得分:3)

使用didInsertElement视图钩子和观察者。

App.ConversationView = Ember.View.extend

  didInsertElement: ->
    @focusOnTextarea()

  modelChanged: (->
    @focusOnTextarea()
  ).observes('controller.model')

  focusOnTextarea: ->
    @$('form textarea').focus()

在从/ 1到/ 2的情况下,路径和视图不会改变。 Ember做的工作量最少。没有必要重新渲染视图,所以它没有。但这也使我绊倒了,我认为这是一个很大的问题。

此外,如果您在视图中覆盖init,请务必致电@_super()

注意:model挂钩仅在登陆页面以反序列化URL时调用,而不是在从其他页面转换并更改模型实例时调用。

答案 1 :(得分:1)

Route#model是你的朋友。它将在每次路由更改时收到包含来自URL的信息的params哈希值(即使在更改正在查看的类的哪个实例时),在您的情况下,

App.ConversationRoute = Ember.Route.extend {
  model: (params) ->
    App.Conversation.find params.conversation_id
  setupController: (controller, conversation) ->
    // you have the correct Conversation object

guides有更多例子。

答案 2 :(得分:1)

如果需要在视图上实例化某些内容,则视图的didInsertElement方法是最佳方法。如果您需要让控制器在模板加载时执行某些操作,您可以将呼叫置于路径的setupController方法中:

App.FirstRoute = Ember.Route.extend({
    setupController: function(controller){
        controller.onload();
    }
});

这是一个完整示例的jsfiddle: http://jsfiddle.net/jgillick/Q5Kbz/

每次加载路线时都会调用此方法。试试jsfidle。单击第二个模板,然后使用浏览器的后退按钮。 onload应该再次开火。

此外,有趣的事实,您可以使用deactivate方法作为卸载,在用户离开该路线时执行该控制器所需的任何操作:

App.FirstRoute = Ember.Route.extend({
  deactivate: function(){
    this.controller.unload();
  }
});

相依

有一点需要注意,(与您的问题没有直接关系)如果您在setupController方法中在控制器上设置模型,则每次加载路径时它都会覆盖您的控制器content属性。为防止这种情况,请在作业周围加上条件:

setupController: function(controller, model) {
  controller.onload();
  if (model && (!controller.content || Ember.keys(controller.content).length === 0)) {
    controller.set('content', model);
  }
}