Conditionally render nested parent route

consider the following routes:

  • post: render the details about a post
  • post/edit: renders editable details about the post (this might be quite different from post)
  • post/comment: renders post AND details about the comment

The issue here is that we need to render the post template in the following two routes: post and post/comment. We explicitly do not want to render the post template on the route post/edit.

Usually one would put stuff that should not be rendered when the child route is active in the corresponding post/index template. However, now we need to copy all that stuff from that template to the post/comment template as well.

Alternatively one might put everything that needs to be shared in post and post/comment into a component. However, now we need to put all our actions into the component as well, violating the DDAU principle or we need to duplicate that logic to post and post/comment controllers.

Lastly, we could make use of the router service and conditionally render only {{outlet}} (edit) or the whole template using a simple if in our post template and a computed property in the controller:

showPost: computed('model', 'router.currentURL', function() {
    return !this.get('router').isActive('post.edit', this.model);

Now when the edit route is active, the parent template is not rendered. On every other child route the template gets rendered.

However this seems to be quite a workaround. Is there a better solution?

I think when situations like this come up you want to keep the solution as simple as possible. Mainly because it will be easier for other Ember developers working on your team to follow.

It sounds like a component might be best here. You have 2 of 3 routes that need to display something, and a 3rd that doesn’t. Components are perfect for this :smiley: Also, I don’t think putting actions inside of components violates DDAU.

Another suggestion would be to come up with a new pathless sub-route that has the post html in it. The tricky part here is naming that sub-route.

this.route('post', { path: 'post/:post_id' }, function() {
  this.route('show', { path: '/' }, function() {


// this gives three routes...
// post.edit

And you can add the post HTML to the post/show template, it won’t end up on the edit page.

Lastly, router service might be ok as well here… at the end of the day you’re using all public APIs there. I think you’re right when you say it seems to be a “workaround” though.

thanks for your reply. That is an interesting idea. Didn’t know that was even possible. However, I don’t think that this is less of a workaround than modifying the template, so I’ll stick with that for now.

I think DDAU is a quite difficult topic to grasp. I remember we started trying to put every action on the route (at least everything that transitions routes or deals with ember data records). By now we have situations where putting those actions into components starts to make sense. Maybe the question is how far one wants to take it concerning making everything DDAU. Doesn’t necessarily always result in better code though :smiley: