3
votes

I have this working example on jsfiddle where I'm showing a list of Posts. When a Post is selected, I display the details in the outlet of the posts template. No problem so far.

Since every Post has many Comments and has many Trackbacks, I'd like to have the post/show template to show two tabs, so I can show either the comments or the trackbacks beneath the details.

For this the post/show template looks like this:

<script type="text/x-handlebars" data-template-name="post/show">
    <h3>{{controllers.post.title}}</h3>
    <p>{{controllers.post.description}}</p>
    <hr/>
    <ul>
        {{#linkTo comments tagName="li"}}<a {{bindAttr href="view.href"}}>Comments</a>{{/linkTo}}
        {{#linkTo trackbacks tagName="li"}}<a {{bindAttr href="view.href"}}>Trackbacks</a>{{/linkTo}}
    </ul>
    {{outlet}}
</script>

The comments and trackbacks routes are basically identical:

App.CommentsRoute = Em.Route.extend({
    setupController: function (controller, model) {
        comments = this.controllerFor('post').get('comments');
        controller.set('content', comments);
    },
    renderTemplate: function () {
        this.render({
            into: 'post/show'
        });
    }
});

My question is about renderTemplate: I would like to render the comments template into to outlet of the post/show template, but this is not working. When I replace the into value with another existing template (e.g. application, posts, post) I do see the comments appear.

What I am doing wrong?

3

3 Answers

3
votes

One great way to help debugging router issues is to turn on the router logging:

window.App = Em.Application.create({
    LOG_TRANSITIONS: true
});

This lets you see which route you are transitioning into. In your case, when navigating to the comments section it shows:

Transitioned into 'posts.index'
Transitioned into 'posts.post.show'
Transitioned into 'posts.post.comments'

This means that your post.show route is not active when you transition to the comments route, which is why you can't render into its {{outlet}}.

Since you are not using the post template for any actual content you can rename your post/show template to post and get rid of the show route. This makes sure that template is still around when you want to insert the comment or trackback template.

App.Router.map(function () {
    this.resource('posts', function () {
        this.resource('post', {
            'path': '/:post_id'
        }, function () {
            this.resource('comments');
            this.resource('trackbacks');
        });
    });
});

Since you changed the template from post/show to post the postController will contain the post passed from posts, so you can drop the controllers.post and access the properties of the post directly:

<script type="text/x-handlebars" data-template-name="post">
...
<h3>{{title}}</h3>
<p>{{description}}</p>
....
</script>

Now all you have to do is update the targeted route to render into, which is now just post:

renderTemplate: function () {
    this.render({
        into: 'post'
    });
}

Working JSFiddle

Update

You can have the show route render into posts route which will replace the post template with your post/edit template:

Updated JSFiddle

App.Router.map(function () {
    this.resource('posts', function () {
        this.resource('post', {
            'path': '/:post_id'
        }, function () {
            this.route('edit');
            this.resource('comments');
            this.resource('trackbacks');
        });
    });
});

App.PostEditRoute = Ember.Route.extend({
    renderTemplate: function() {
        this.render({into: 'posts'});   
    }
});
1
votes

It is a little strange, but you have to tell the route to render the post/show again.

Here is a jsfiddle.

renderTemplate: function () {
    this.render('post/show');
    this.render({
        into: 'post/show'
    });
}

Update: fixed the link

0
votes

If you want to render the template into a different named outlet

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

Reference: Ember Documentation