Search code examples
ember.jsember-router

Emberjs Modals on a route


So I am trying to figure out how best to put modals on a route, such that you can navigate to them via the url.

application.hbs

{{outlet}}

{{outlet modal}}

There is a discussion here and emberjs cookbook provides another example but nothing covers how you can have modals on a specific route.

The closest thing I have seen is this Stack Overflow question but it suffers from two problems:

  1. When the modal route is visited, the view in the main outlet gets destroyed. So in your UI, things underneath the modal get wiped out.
  2. history.back() is that you essentially revisit that route causing that view to be redrawn and feels very hackish.

This is where I feel a solution would exist but not sure what exactly:

App.MyModalRoute = Ember.Route.extend({

renderTemplate: function(controller, model) {

  /**
   * When my modal route is visited, render it in the outlet
   * called 'modal' but somehow also persist the default outlet.
   **/
   this.render({ outlet: 'modal' });   
} 

});


Solution

  • Here is how we handle it:

    In the route you use a render piece similar to what you described:

    App.UserDeleteRoute = Ember.Route.extend({
      renderTemplate: function() {    
        this.render({
          into: 'application',
          outlet: 'modal'
        });    
      },
    
      actions: {
        closeModel: function() {
          this.transitionTo('users.index');
        }
      },
      deactivate: function() {
        this.render('empty', {
          into: 'application',
          outlet: 'modal'
        });
      }  
    }
    

    Clearing out outlet on the "deactivate" hook is an important step.

    For the main template all you need is:

    {{outlet}}
    {{outlet "modal"}}
    

    This does not override the default outlet.

    One thing you may want to do for all your modals is implement a layout:

    App.UserDeleteView = Ember.View.extend({
      layoutName: 'settings/modals/layout',
      templateName: 'settings/modals/user_delete'
    });
    

    Another gotcha is that there needs to be a parent route rendered into the main outlet. If whatever is in that outlet is not the parent of your modal, then the act of moving away from that route will remove it from the outlet.

    working JS bin