Route Constraints

The following three constraints apply to route names. They will only work with {{liquid-outlet}} because only {{liquid-outlet}} has visibility into routes. (The other helpers like {{liquid-if}}) don't know anything about routes.)

fromRoute
Matches the route name at the start of a transition.
toRoute
Matches the route name at the end of a transition.
withinRoute
Matches the same name at both the start and end of the transition. This is good for matching transitions that are not route changes.

Each of them accepts one argument. The argument can be a string route name, a function that tests route names, or a list of either of those.

The next three constraint apply to routes' models. They too only work with {{liquid-outlet}}.

fromModel
Matches the route's model at the start of a transition.
toModel
Matches the route's model at the end of a transition.
betweenModels
A shorthand for both fromModel and toModel.

Each of them accepts a function for testing the model, which receives the model as its first argument and should return a boolean. You have optional access to the other model in the second argument (that is, a fromModel matcher receives (oldModel, newModel) and a toModel matcher receives (newModel, oldModel)).

Examples:

// Matches any transition that ends up in the route named 'foo', no
// matter where it came from.
this.transition(
  this.toRoute('foo'),
  this.use('toLeft')
);

// This is equivalent to the previous example, but showing a more
// generic form that lets you provide an arbitrary test.
this.transition(
  this.toRoute(function(routeName){ return routeName === 'foo'; }),
  this.use('toLeft')
);

// You can list multiple routes, and the constraint will be satisfied
// by any of them. This will match any transition that ends up in 'foo'
// or 'bar'.
this.transition(
  this.toRoute(['foo', 'bar']),
  this.use('toLeft')
);

// You can mix and match strings and functions. This is equivalent to
// the previous example.
this.transition(
  this.toRoute(['foo', function(routeName){ return routeName === 'bar'; }]),
  this.use('toLeft')
);

// All of these examples apply to fromRoute too. This will match any
// transition from 'foo' to 'bar', or from 'foo' to any route name
// starting with 'q'.
this.transition(
  this.fromRoute('foo'),
  this.toRoute(['bar', function(routeName){ return /^q/.test(routeName); }]),
  this.use('toLeft')
);

// withinRoute is just a shorthand. Instead of saying this:
this.transition(
  this.fromRoute('foo'),
  this.toRoute('foo'),
  this.use('toLeft')
);
// you can say this:
this.transition(
  this.withinRoute('foo'),
  this.use('toLeft')
);

In case, you need to animate subroute transitions for a nested UI and you don't have an "index" route or template defined:

<!-- main-route.hbs -->
<header></header>
<sidebar>{{liquid-outlet}}</sidebar>

<!-- main-route.edit.hbs -->
<h1>Edit</h1>

You can write a rule for an empty outlet, as follows:

this.transition(
  this.fromRoute(null),
  this.toRoute('main-route.edit'),
  this.use('toUp')
);