8

I would have thought that the LoadingRoute would display its template in the {{outlet}} of the main AppView, but it doesn't seem like it does. What determines where it goes?

Here's a JS Bin of my problem. The Loading message isn't showing up where I expect.

Sam Selikoff
  • 12,366
  • 13
  • 58
  • 104

4 Answers4

5

Indeed it looks that it is inserted right before the closing tag of the tag with class ember-application. You can control to which outlet it is inserted using renderTemplate:

App.LoadingRoute = Ember.Route.extend({
  renderTemplate: function() {
    this.render('loading', {
      outlet: 'loading',
      into: 'application'
    });
  }
});

Then place the loading outlet wherever you want in the application template:

<script type="text/x-handlebars" data-template-name="application">
  <div id="twenty-fifth-cdu-production">

    {{#view App.Sidebar}}
    <div id="left-panel">
      <ul>
      <li><a href="#one">One</a></li>
      <li><a href="#two">Two</a></li>
      <li><a href="#three">Three</a></li>
      </ul>
    </div>
    {{/view}}

    <div id="center-panel" class="container-fluid">
      {{outlet}}
      {{outlet "loading"}}
    </div>
  </div>
</script>

Note that the name of the default outlet (i.e., {{outlet}}) is main. But trying to use the default outlet for rendering the App.LoadingView creates problems.

Demo: http://jsbin.com/asizim/2/

Panagiotis Panagi
  • 9,927
  • 7
  • 55
  • 103
3

Suppose that you have this mapping:

App.Router.map(function() {
  this.route("foo")
});

When is transitioned to foo route. It template will be inserted in that was specified in the into property of render method. By example:

App.FooRoute = Ember.Route.extend({
    renderTemplate: function() {
      this.render("foo", { into: "sometemplate" })
    }
});

Case this isn't setted, the foo route will retrieve the parent route, in that case ApplicationRoute, and insert the template foo, into application template. This is the default behavior when you don't override the renderTemplate method.

But when no one of that conditions happens, this is the behavior of LoadingRoute, because it doesn't have the ApplicationRoute as parent. Than ember insert the template in the body tag, or more specifically in App.rootElement.

Marcio Junior
  • 19,078
  • 4
  • 44
  • 47
  • I didn't understand the hierarchy. I think this best answers my question - thanks! – Sam Selikoff Jul 25 '13 at 04:00
  • In that question http://stackoverflow.com/questions/16476977/ember-js-transition-to-nested-routes-where-all-routes-are-dynamic-segments-from is used a multi level route mapping. This create a kind of hierarchy. The ApplicationRoute is the toppest in the hiearchy and it is the parent for all routes mapped by this.route("myroute"). But at the moment LoadingRoute behaves diferent. – Marcio Junior Jul 25 '13 at 04:22
  • Thanks! I meant, I didn't understand the hierarchy until you explained it. I get it now :) – Sam Selikoff Jul 25 '13 at 04:26
1

If you increase the timeout you will be able to notice that loading template is attached at the end of document. It is probably designed to be used with overlays of fixed positioned elements.

You can add another outlet (called loading in example below) and force rendering of loading template into it with Route renderTemplate hook:

App.LoadingRoute = Ember.Route.extend({
    renderTemplate: function() {
        this.render("loading", { outlet: 'loading', into: 'application' });
    }
});

Check out this example: http://jsbin.com/ipagut/5#/#two

chrmod
  • 1,415
  • 12
  • 19
  • I'm getting an error: `Uncaught TypeError: Cannot call method 'connectOutlet' of undefined`. Unfortunately I'm having a hard time reproducing in JsBin. Any ideas? – Sam Selikoff Jul 24 '13 at 16:54
  • Did you created additional, *named* outlet in you application template? – chrmod Jul 24 '13 at 18:21
  • yes. When I call `this.render('loading'...` I get an error within ember's code saying the parentview is undefined. – Sam Selikoff Jul 24 '13 at 18:39
  • Seemed like the path hadn't changed yet? I wrapped your `this.render` code in a conditional: `if ((this.controllerFor('application').get('currentPath')) {...`. Any idea why that's happening? – Sam Selikoff Jul 24 '13 at 18:50
0

My guess is that this behavior is intentional, so the LoadingRoute could work while the ApplicationRoute itself is loading. Rendering the application template manually should allow you to render into one of its outlets.

App.LoadingRoute = Ember.Route.extend({
    renderTemplate: function() {
        this.render("application");
        this.render("loading", { outlet: "loading", into: "application" });
    }
});
Milo
  • 46
  • 2
  • Yes, I think this is right. The default is for the loading route to append its template to the body. I think that's where I was confused. In your example, I don't think you need to even call `this.render('application')`. – Sam Selikoff Aug 14 '13 at 13:26