emberjs/ember.js — pull request #3069 by machty (2013-07-30 15:32:48+00:00)
Title: this.route in DSL is nestable, preserves namespace

This removes the restriction that only `this.resource` can have nested
child routes. This is a frequently requested feature as the
namespace-resetting with `this.resource` is often surprising and
restricting, and preserving the namespace of generated objects for
child routes can only be accomplished via repetitive and uninituitive
constructs, such as

this.resource('foo', function() {
this.resource('foo.bar', function() {
this.resource('foo.bar.baz', function() {
// All this repetition to get an
// intuitively-named FooBarBazRoute
});
});
});

So, `this.route` can be nested like `this.resource`, but unlike
`this.resource`, the namespace of child routes is appended rather
than reset to a top-level namespace, allowing the above to be
written as:

this.route('foo', function() {
this.route('bar', function() {
this.route('baz', function() {
// Simpler, still uses FooBarBazRoute
// (and, like resource, generates foo.bar.baz.index
// and FooBarBazIndexRoute since we've provided
// an [albeit empty] callback)
});
});
});

Unnested `this.route` works the same way as before. We're only
adding functionality, not changing / removing any.

This also makes it possible to reuse route declarations in
`App.Router.map` for a macro-based approach to sharing route
hierarchies, e.g.:

function commentableRoute() {
this.route('comments', function() {
this.route('new');
this.route('search');
//...
});
}

App.Router.map(function() {
// the use of route/resource here doesn't
// matter since we're top-level
this.resource('posts', commentableRoute);
this.resource('articles', commentableRoute);
});

There's still more work to do make it easier to share logic
between routes, and the above technique could certainly be more
robust, but this gets a major roadblock out of the way that lots
of people have been complaining about.