What is the correct way to enter and exit modal states with Ember router v2?

I cannot figure out how to properly handle modal states / views with the new Ember router. More generally, how do you handle states that you can enter and exit without affecting the "main" state (URL)?

For example, the button "New message", which is always available regardless of the current state of the sheet. Clicking New Message should open a new text message for the current view without affecting the URL.

I am currently using this approach:

Routes

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}} 

I obviously forgot about some code for brevity.

This approach "works", but has two problems mentioned above:

  • I use the private API to remove the modal view in the hideModal event hideModal .
  • I need to specify the application template in all my routines, because if I do not, the default implementation of renderTemplate will try to display in the modal template instead of the application, if you open the modal, close it, and then go between the input and archive states (since modal template became lastRenderedTemplate for IndexRoute).

Obviously, none of these problems is a transaction handler, but it would be nice to find out if there is a better approach that I am missing, or is it just a gap in the current router API.

+7
source share
2 answers

We do the same, but do not get access to the private API. I don’t know if our solution is the best practice, but it works.

In the events of our RootRoute , I have an event (the same as your newMessage ), where we create the view that needs to be displayed, and then add it.

 events: { showNewSomething: function(){ var newSomethingView = app.NewSomethingView.create({ controller: this.controllerFor('newSomething') }); newSomethingView.append(); } } 

This adds a modal look to our application. When canceling or saving to newSomethingView we call this.remove() to destroy the view again and remove it from the application.

Again, this doesn't sound like best practice, but it works. Feel free to comment on this if anyone has a better solution.

+4
source

I don’t know if you are using Bootstrap Modal script or which one, but if so, this question has a suggested solution. I haven’t figured out all the parts yet, but I’m looking for the same solution myself to be able to use Colorbox in “Smart Best Practices” - a compatible way.

0
source

All Articles