1
votes

I'm trying to understand Ember routing and template rendering with a simple example. I have a page like the following:

<html>
    <head>.....</head>
    <body>
        <script type="text/x-handlebars" data-template-name="cars">
            cars<br/>
        </script>

        <script type="text/x-handlebars" data-template-name="cars/new">
            cars new
        </script>

        <script type="text/x-handlebars">
              <header id="header">
                {{outlet header}}
              </header>

              <section id="main">
                {{outlet main}}
              </section>

              <footer id="footer">
                Some footer
              </footer>
        </script>

        <!--lib files-->
        <!--script will go here-->
    </body>
</html>

Throughout the application, all contents need to be entered in the main outlet. I have a javascript file with the following contents:

window.App = Ember.Application.create();
App.Router.map(function() {
  this.resource("cars",function (){
    this.route("new");
  });
 });

App.ApplicationAdapter = DS.FixtureAdapter.extend();

App.CarsRoute = Ember.Route.extend({
  renderTemplate: function() {
    this.render({ outlet: 'main' });
  }
});

App.CarsNewRoute = Ember.Route.extend({
  renderTemplate: function() {
    this.render({ outlet: 'main' });
  }
});

The problem is that cars template is properly being rendered while cars/new isn't. How can I correct this issue ?

2
It's possible--not sure--that it's trying to render into an outlet named new in the cars template. (Although in that case I would expect a run-time error--do you see anything?) Try removing the name main from {{outlet main}}, and killing the renderTemplate methods and see what happens.user663031
nopes same thing, I kinda understand the reason why this is happening, cars template is rendering because in the application template there is an outlet, while cars template, there isn't any outlet, if I add an outlet in cars template, cars/new template gonna render, but together with the cars template content which I don't want, I'm wishing to direct where to render a templateNoor
You could try playing around with the index routes. If you don't want to do that, and you are having a cars template, then it MUST contain an output for its subroutes to render into. Add an empty {{outlet}} and I predict cars/new will render into that.user663031
if I add an {{outlet}} to cars template, the cars/new template surely gonna render there, but it gonna render together with the content of cars template which i don't wantNoor
Then create a cars/index template.user663031

2 Answers

1
votes

Not sure all the outlets are necessary--but I think the simplest change that can get you running is to change

<script type="text/x-handlebars" data-template-name="cars">

to

<script type="text/x-handlebars" data-template-name="cars/index">

and add

<script type="text/x-handlebars" data-template-name="cars">
    {{outlet}}
</script>

The issue is that it's using cars template as the parent template for cars/index and cars/new. Ember will try to render cars/new into an outlet, but you haven't specified one in cars. Ember will figure out how to make it happen if you omit the cars template, but not without a notice in your console.

0
votes

tWhen you explicitly tell a route to render in a specific outlet, I believe you need to disconnect from that outlet before something new can be rendered in it. Especially if the new route is a child of the existing route in that outlet.

Typically you will want to render cars into a generic {{outlet}} and cars/new should render into another {{outlet}} within the cars template.

If you want to continue doing this the way you want, you will need to call disconnectOutlet() in an action like willTransition() before the new template can be rendered. But I can imagine that would get confusing fast.

for what it's worth, this is how i would attempt it.

renderTemplate: function() {
    this.render({
        into: 'application',
        outlet: 'main'
    });
},    
actions: {    
    willTransition: function() {
        this.disconnectOutlet({
            outlet: 'main',
            parentView: 'application'
        });
    }
}

some other things to consider:

if an error were to occur, ember would not automatically switch to a substate. you would also need to explicitly define the errors route to do this... same thing for loading substates... and literally every route in your app would need to connect and disconnnect from the main outlet