Ember Routes

Aaron Haurwitz

@ahaurw01

github.com/ahaurw01

UI Team Lead at Resonate

What's up with routing?

  • The Web is made of resources
  • Every application state is a unique URL

Ember Route Responsibilities

  • Executes application state logic
  • Fetches the model
  • Renders the template

How to Define Your Routes


  App.Router.map(function () {
    this.route('about');
    this.route('contact', {path: '/contact-us'});
    this.resource('cats', function () {
      this.route('create');
      this.resource('cat', {path: '/:cat_id'}, function () {
        this.route('edit');
      });
    });
  });
          

Dynamic Segments


  { path: '/posts/:post_slug' }
          
  • Path param value is passed to route model callback, much like server side routing
  • You can have multiple dynamic segments.
  • { path: '/person/:first_name/:last_name' }
  • You can nest things under a resource
  • Dynamic url is deserialized to let you look up the model
  • Model is serialized to make the dynamic url

Nesting Routes, Nesting Templates

  • Routes nested under a resource render their template into that resource's {{outlet}}
  • Nest arbitrarily deep
  • Parent-level templates don't get ripped out of the DOM when navigating to sibling
  • Thus, a single URL can represent several nested states
JS Bin

Only implement if you want to...

  • this.route('about') => App.AboutRoute
  • Get it for free if not implemented!
  • this.resource('cat') => App.CatRoute
  • this.resource('cat', function () {...}) => App.CatRoute, App.CatIndexRoute
  • no template == {{outlet}}

  App = Ember.Application.create({
    LOG_ACTIVE_GENERATION: true
  });
          

Application and Index Routes

  • Don't need to specify in Router.map()
  • Override only if you want to
  • ApplicationRoute entered once, all events bubble up to her
  • IndexRoute represents '/'

Model Hooks

  • Route#model - fetch the model for the route
  • Route#beforeModel - optional validations before running model()
  • Route#afterModel - optional validations after running model()
  • Transition pauses when a Promise is returned
JS Bin

Loading Routes

  • loading event fired when Promise returned from model hooks
  • Default loading event handler enters sibling *LoadingRoute
  • WILL NOT enter higher up *LoadingRoutes
  • You can handle loading event all the way up to ApplicationRoute

Error Routes

  • error event fired when *model Promise rejects or error is thrown
  • Default error event handler enters *ErrorRoute
  • IT WILL enter any *ErrorRoute up the chain/li>
  • Can handle error event all the way up to ApplicationRoute
JS Bin

Transitions

  • willTransition event fired on current route when you attempt to navigate away
  • model hooks provide you with current transition object
  • transition.abort(), transition.retry()
JS Bin

Redirecting


  // Navigate to /about
  this.transitionTo('about');

  // Navigate to /posts without adding history
  this.replaceWith('posts');

  // Navigate with model
  this.transitionTo('cat', mrMcSnuggles);

  // Navigate using identifier
  this.transitionTo('puppy', 17);
          
  • Cancels current transition if one exists

Query Parameters

  • Currently feature-toggled
  • Visible in the URL but support is baked into controllers
  • http://example.com/#/posts?author=zach
JS Bin

Authentication Example