Something I have noticed recently with Ember Router is it only allows navigating to leaf routes — routes without child routes.
Now unless I'm doing things incorrectly then this seems like a bug/mistake in design.
Let's take for example something like this:
I have a collection of projects, each project has many collaborators, with this I want to build a UI with a 3 column layout (something like your standard desktop email client) where on the left I have a list of projects, when clicking on a project the middle column shows a list of collaborators, and clicking on a collaborator loads its details into the righthand column.
Now with the routing I want to navigate to /projects/1
when clicking on a project and onto /projects/1/collaborators/23
when clicking on a collaborator.
Here is a router illustrating the first part of nested route:
App.reopen(
Router: Ember.Router.extend(
enableLogging: true
location: 'hash'
root: Ember.Route.extend(
index: Ember.Route.extend(
route: '/'
redirectsTo: 'projects'
)
projects: Ember.Route.extend(
# This route is not routable because it is not a leaf route.
route: '/projects'
connectOutlets: (router) ->
# List projects in left column
router.get('applicationController').connectOutlet('projects', App.projects)
show: Ember.Route.extend(
# This route is routable because it is a leaf route.
route: '/:project_id'
connectOutlets: (router, project) ->
# Render the project into the second column, which actually renders
# a list of collaborators.
router.get('projectsController').connectOutlet('project', project)
)
)
)
)
)
As you'll see Ember doesn't call updateRoute (set the URL) until transitioning to root.projects.show
because of this line https://github.com/emberjs/ember.js/blob/master/packages/ember-routing/lib/routable.js#L81
Has anyone else done anything like this? Is there a better way to design this?
It can render a template. It can load a model that is then available to the template. It can redirect to a new route, such as if the user isn't allowed to visit that part of the app. It can handle actions that involve changing a model or transitioning to a new route.
Basic Routes. The map() method of your Ember application's router can be invoked to define URL mappings. When calling map() , you should pass a function that will be invoked with the value this set to an object which you can use to create routes.
Since then the StateManager has been replaced with a more thorough implementation named Ember Router.
A Transition is a thennable (a promise-like object) that represents an attempt to transition to another route. It can be aborted, either explicitly via abort or by attempting another transition while a previous one is still underway. An aborted transition can also be retry() d later.
The best way I've found to do this is to have a root.projects.index
state with a route of "/" and nothing else. This way every page has it's own specific state.
projects: Ember.Route.extend(
# This route is not routable because it is not a leaf route.
route: '/projects'
connectOutlets: (router) ->
# List projects in left column
router.get('applicationController').connectOutlet('projects', App.projects)
index: Ember.Route.extend(
route: "/"
)
show: Ember.Route.extend(
# This route is routable because it is a leaf route.
route: '/:project_id'
connectOutlets: (router, project) ->
# Render the project into the second column, which actually renders
# a list of collaborators.
router.get('projectsController').connectOutlet('project', project)
)
)
N.B. That being said I'm doing a similar thing with a 3 column layout, and am matching the middle and right column to the routes as above and adding the left column in a shared layout to each of the possible middle views.
I think this issue is resolved. I am using ember routes without an index and do not face any leaf state issues. I was browsing why we need an index at all and I landed up here. Is there any other reason for using the index state too?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With