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