Sharing A Parent Model Across Route Boundaries
Just last week Alex LaFroscia released a new addon called Ember Context and I wanted to share some patterns that I've used in the past that this addon changes.
The Problem
Sometimes you have a UI where at a certain level you have multiple nested routes and they deal with one parent item. For example if you had a blog management system that supported multiple blogs, you could have a route like dashboard.blog.post.edit
and the Blog
model is found at the dashboard.blog
route. So at this point you want to use that same blog model in the other routes. Historically there has never been a great way to do this, you might think put it on a service, but then you have to register and cleanup that service since services are global. Along with that inconvenience it's also not clear where the service gets its data, it seems a bit magic.
The Past
In the past I've tackled this problem with the modelFor
route method, something like:
Now I can access the blog in my template via {{@model.blog}}
, and it all works. The issue here is that modelFor
will return whatever data you returned in the model
hook of the dashboard.blog
route, and that could change to an object of items, like { config, blog }
and now you need to visit every modelFor
and change the assumption there. In cases where a route doesn't have any other model data you need to fetch, you still have to add a route file and do this whole dance.
The Present
With the new ember-context
addon, we get to change this to something with less boilerplate, and a bit clearer about where the data is coming from. With this addon we'd define the following in our dashboard.blog
template:
Now in our dashboard.blog.post.edit
template we can use this blog model by using a helper: {{consume-context 'blog'}}
:
And if we wanted to access it in a controller or a component, it would be as simple as injecting the value: