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

在Ember.js应用程序中检测路由/视图转换,ember.js,Ember.js,我的应用程序的路由器如下所示(它是CoffeeScript): 因此,在我的应用程序中,我有一些路径,如/new,/1,/2,等等 我想检测从/1到/2的转换,以便在我的视图中进行一些初始化(基本上,将焦点放在textarea字段上)。不幸的是,由于/1和/2使用相同的路径,因此几乎不可能检测到这种转换 我尝试在视图中使用didInsertElement(如上所述)或在控制器中观察currentPath(如上所述)。如果我从/new到/1(不同的路线),它可以正常工作,但如果我从/1到/2,它就

我的应用程序的路由器如下所示(它是CoffeeScript):

因此,在我的应用程序中,我有一些路径,如
/new
/1
/2
,等等

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

我尝试在视图中使用
didInsertElement
(如上所述)或在控制器中观察
currentPath
(如上所述)。如果我从
/new
/1
(不同的路线),它可以正常工作,但如果我从
/1
/2
,它就不能正常工作

我发现建议使用
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()

}
但我仍然不知道如何使这两件事一起工作(这是一个问题,因为我读到控制器不应该知道视图)

谢谢你的帮助

Route#model
是您在这里的朋友。它将收到一个
params
散列,其中包含在您的案例中每次路由更改(即使仅更改正在查看的类的实例)时从URL获得的信息

App.ConversationRoute = Ember.Route.extend {
  model: (params) ->
    App.Conversation.find params.conversation_id
  setupController: (controller, conversation) ->
    // you have the correct Conversation object
这里有更多的例子。

路线#模型
是您的朋友。它将收到一个
params
散列,其中包含在您的案例中每次路由更改(即使仅更改正在查看的类的实例)时从URL获得的信息

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

有更多示例。

使用
didInsertElement
查看挂钩和观察者

App.ConversationView = Ember.View.extend

  didInsertElement: ->
    @focusOnTextarea()

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

  focusOnTextarea: ->
    @$('form textarea').focus()
在从/1转到/2的情况下,路线和视图不会改变。余烬做尽可能少的工作。不需要重新渲染视图,因此不需要。但这也把我绊倒了,我想这是个大问题

另外,如果您在视图中覆盖了
init
,请确保调用
@\u super()


注意:
model
钩子仅在登录到页面以反序列化URL时调用,而不是从另一个页面转换并更改模型实例时调用。

使用
didInsertElement
查看钩子和观察者

App.ConversationView = Ember.View.extend

  didInsertElement: ->
    @focusOnTextarea()

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

  focusOnTextarea: ->
    @$('form textarea').focus()
在从/1转到/2的情况下,路线和视图不会改变。余烬做尽可能少的工作。不需要重新渲染视图,因此不需要。但这也把我绊倒了,我想这是个大问题

另外,如果您在视图中覆盖了
init
,请确保调用
@\u super()


注意:
model
钩子仅在登录到某个页面以反序列化URL时调用,而不是在从另一个页面转换并更改模型实例时调用。

如果需要在视图上实例化某些内容,视图的
didInsertElement
方法是最好的方法。如果在加载模板时需要控制器执行某些操作,可以将调用放入路由的
setupController
方法中:

App.FirstRoute = Ember.Route.extend({
    setupController: function(controller){
        controller.onload();
    }
});
下面是一个JSFIDLE,其中包含一个完整的示例:

每次加载该路由时都将调用该函数。试试jsfidle。单击第二个模板,然后使用浏览器的“后退”按钮。装载的子弹应该会再次开火

另外,fun fact,您可以使用
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);
  }
}

如果需要在视图上实例化某些内容,视图的
didInsertElement
方法是最好的方法。如果在加载模板时需要控制器执行某些操作,可以将调用放入路由的
setupController
方法中:

App.FirstRoute = Ember.Route.extend({
    setupController: function(controller){
        controller.onload();
    }
});
下面是一个JSFIDLE,其中包含一个完整的示例:

每次加载该路由时都将调用该函数。试试jsfidle。单击第二个模板,然后使用浏览器的“后退”按钮。装载的子弹应该会再次开火

另外,fun fact,您可以使用
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);
  }
}

不。如果要更改子路由上的参数,则不会每次调用setupController。迪迪塞勒门诺也不会。如果要更改子路由上的参数,则不会每次调用setupController。迪迪塞特也不会