我的应用程序的路由器看起来像这样(它是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()
}
但是我仍然无法弄清楚如何让这两件事情一起工作(这是一个问题,因为我读到控制器不应该知道视图)。
感谢您的帮助!
答案 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);
}
}