我无法弄清楚使用新的Ember路由器处理模态/视图的正确方法.更一般地说,如何处理可以进入和退出而不影响“主”状态(URL)的状态?
例如,无论当前叶状态如何,始终可用的“新消息”按钮.单击“新消息”应在当前视图上打开新消息模式,而不会影响URL.
目前,我正在使用这样的方法:
路线:
App.Router.map(function() { this.route('inBox'); this.route('archive'); }); App.IndexRoute = Em.Route.extend({ ... events: { newMessage: function() { this.render('new_message',{ into: 'application',outlet: 'modalView' }); },// Clicking 'Save' or 'Cancel' in the new message modal triggers this event to remove the view: hideModal: function() { // BAD - using private API this.router._lookupActiveView('application').disconnectOutlet('modalView'); } } }); App.InBoxRoute = Em.Route.extend({ ... renderTemplate: function(controller,model) { // BAD - need to specify the application template,instead of using default implementation this.render('inBox',{ into: 'application' }); } }); App.ArchiveRoute = ... // basically the same as InBoxRoute
application.handlebars:
<button {{action newMessage}}>New Message</button> {{outlet}} {{outlet modalView}}
为了简洁,我显然遗漏了一些代码.
这种方法“有效”,但有上述两个问题:
>我正在使用私有API删除hideModal事件处理程序中的模态视图.
>我需要在所有子路径中指定应用程序模板,因为如果我不这样做,则渲染模式,关闭它然后导航时,renderTemplate的默认实现将尝试渲染到模态的模板而不是应用程序中.收件箱和存档状态之间(因为模态的模板已成为IndexRoute的lastRenderedTemplate).
显然,这些问题都不是破坏者,但是如果知道是否有一种更好的方法是我缺失的,或者这只是当前路由器API中的一个缺口,那将是很好的.
解决方法
我们做同样的事情,但没有访问私有API.
我不知道我们的解决方案是否是最佳实践,但它确实有效.
我不知道我们的解决方案是否是最佳实践,但它确实有效.
在我们的RootRoute的事件中,我有一个事件(与你的newMessage相同),我们创建我们需要渲染的视图,然后追加它.
events: { showNewSomething: function(){ var newSomethingView = app.NewSomethingView.create({ controller: this.controllerFor('newSomething') }); newSomethingView.append(); } }
这会将模态视图附加到我们的应用程序中.
在取消或保存在newSomethingView中时,我们调用this.remove()来销毁视图并再次从应用程序中删除它.