Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Ember Router only allow navigating to leaf routes?

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?

like image 451
Ivan Avatar asked Jul 08 '12 03:07

Ivan


People also ask

How does Ember routing work?

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.

How to generate route in Ember?

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.

What has to replaced with a more thorough implementation named Ember router?

Since then the StateManager has been replaced with a more thorough implementation named Ember Router.

Can you transition in Ember?

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.


2 Answers

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.

like image 182
Bradley Priest Avatar answered Sep 30 '22 12:09

Bradley Priest


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?

like image 36
inertia Avatar answered Sep 30 '22 13:09

inertia