Master-detail view with components


#1

I currently have a master-detail style setup using named outlets which seems to work fine. With the emphasis of components being the future I am wondering how I can use components for this instead of named outlets.

The problem I am having is that I cannot pass the model for the detail view to the component because the component lives in a route higher up. Let me explain.

The ‘/users’ route renders the ‘users.hbs’ template and in that template I call a ‘user-detail’ component. What I would like is for that user-detail component to be supplied with a user model when the /users/:user_id route is visited. As the component doesn’t live on the ‘/users/:user_id’ level I have no way to pass it the model.

I could just call the component in ‘users/detail.hbs’ instead, but then all my future detail views would be limited to existing within this components template, ideally I would like to render these in ‘users.hbs’ so that I have more flexibility on placement.

Is there a correct way to do this or are components just a bad fit for this design?

Please let me know if I have not explained this very well, it hurt my head just writing it!

Regards Jack


#2

You should be able to grab the user model in your parent route’s model hook and then pass it to the component. Do you mind including your folder layout and some relevant code of what you’ve tried so far?


#3

Hi vikram7

Unless I am missing something I don’t think I can do that since the /users route gets all the users and not the currently selected user. The component is being rendered at the /users level so that I can make use of the entire users template and not be limited to the detail.hbs template. I think this is the problem but I’m not sure if it can be worked around.

Basic folder structure:

app
|-- components
|   |-- user-detail.js
|
|-- controllers
|-- helpers
|
|-- models
|   |-- user.js
|
|-- routes
|   |-- users.js
|
|-- templates
|   |-- components
|   |   |-- user-detail.hbs
|   |-- users
|   |   |-- detail.hbs
|   |
|   |-- application.hbs
|   |-- users.hbs
|
|-- app.js
|-- router.js
|-- index.html

app/routes.js:

Router.map(function() {
  this.route('users', function() {
    this.route('detail', { path: ':user_id' })
  });
});

app/templates/users.hbs:

{{outlet}}
{{'user-detail'}}

This is a very basic representation so I may have missed some minor details. Here we can see that at the /users route the app/templates/users.hbs template is rendered. In that template I render a ‘user-detail’ component.

I’d like that user-detail component to be given the model for a specific user when /user/1 is visited. This is easily done if i render a user-detail component in templates/users/detail.hbs but then I am limited to having the component within the users.hbs outlet.

With named outlets I can simply place {{outlet ‘detail’}} in users.hbs and specify the following in app/routes/users/detail.js:

export default Ember.Route.extend({
  renderTemplate() {
    this.render({
        outlet: 'detail'
    });
  }
});

This will look for the outlet named ‘detail’ in app/templates/users.hbs and everything is fine. I am however trying to do this with components of course but I can’t get my head around how to replicate the same functionality.

Is this possible to do “correctly” with Ember and components? Or should I just stick with named outlets?