Data access with multiple named outlets


#1

I’m evaluating ember for some future projects (and possibly interested in contributing to the documentation) and I’m trying to get a grasp of some of the key features of the framework. I’ve run into one aspect that has me scratching my head a little and I would appreciate any insights that others may be able to provide…

The nested template structure of an ember app and the way that a URL maps onto a particular arrangement of templates and related data models are clearly fundamental aspects of how the framework works. My understanding, very briefly, is that a URL maps onto (potentially) an ordered sequence of nested routes, each of which may be associated with a data model. Each route in that sequence may also identify (explicitly or by default) one or more templates to be rendered into either a default or a named outlet contained in an ancestor template.

Most of the examples I’ve seen seem to fit the sequential route model pretty naturally… e.g. a playlist containing albums containing tracks, or a notes app containing notebooks containing notes etc. In most of these kinds of cases, parent templates often have a single outlet accommodating a single child template.

Of course there are exceptions… for example in the guides we see this:

export default Ember.Route.extend({

  renderTemplate() {
    this.render('favoritePost', {
      into: 'posts',
      outlet: 'post',
      controller: 'blogPost'
    });
    this.render('comments', {
      into: 'favoritePost',
      outlet: 'comment',
      controller: 'blogPost'
    });
  }

});

allowing two different templates to be rendered into two different named outlets by a single route (though even here the templates are still organized sequentially, with ‘comments’ contained within ‘favoritePost’ contained within ‘posts’).

As far as I can tell from the little experimentation I’ve done, in a case like this each of these different templates only has access to the same data model, the one (not shown above) associated with the route that is invoking them. Notwithstanding the fact that you can apparently define different controllers, my understanding is that you can’t define separate data models for separate templates rendered in this way even if they are conceptually quite distinct.

The reason I highlight this is that it seems to impose some constraints on the way the application is structured that to my mind don’t feel quite so natural. I can think of examples where I want to render two or more sets of quite different objects, say ‘most recent articles’ and ‘most popular publications’. In a Rails app I’ve built, the page url in this case would be something like ‘articles’, routed to an index action, but the page would also include a jQuery ajax request to a separate url requesting the publication data once the initial page has loaded.

Thinking about how something like this would look in ember, it seems to make sense to me that the articles and publications would be rendered by separate sibling templates rendered into named outlets within a single parent. But if my understanding is correct the data they display would have to be defined within the route that invokes them both, presumably by an aggregated model containing both sets of records (although I haven’t dug enough yet to know whether that’s actually feasible).

Am I barking up the wrong tree here? (completely new to ember, so it’s quite possible.) The idea of aggregating data in a model just because it’s being displayed on the same page feels a little unseemly to me.

Appreciate any comments.


#2

If you want to render post and authors you just pass them to a component. You can do this from any route. Like this:

On the route you have to do controller.setProperties(models); to get the models:

I am still learning and and a beginner and maybe my code is not the best way to do things. But I hope this helps you somehow.


#3

Thanks Martin. That’s quite helpful, although the templates here are still nested only sequentially and in this particular example it looks like authors doesn’t actually get used anywhere in the component. However it does confirm and illustrate my thought about needing to aggregate the two different types of data in the model, and the use of setProperties to make them accessible individually is a nice feature. I see how this is subsequently picked up in the post controller.


#4

I still need to get rid of the needs: in the post controller. So if you find a better way please write a PR or report back.

authors is passed to the blog-post-edit component for ember-selectize


#5

Thanks, I did miss that. I was only looking at the template.