Throughout the Ember.js documentation, one finds the concept of dynamic segment mentioned at several places. What does it mean?
1 Answers
Updating with a proper sample: Demo | Source
Edit due to questions in comments:
In Ember, think of the Router
mechanism as a State Machine: Each Route
can be seen as a State. Sometimes tho, a state can have it's own little state machine within it. With that said: A resource
is a state which you have possible child states. A PersonRoute
can be defined as either as a resource
our a route
in the <Application>.Router.map
callback; it really depends on your end goal. For example, if we think of a resource for a list of people based on a person model, we would potentially have a route to list all records.
App.Router.map(function() {
this.resource('people');
});
With this map, I'm telling my app that it needs a people template (and maybe a view), a people controller and a people route. A resource is also assumed to have a index route, which is implied and you don't have to code it, but if you need to, it would be PeopleIndexRoute
, after the name of the resource itself, by convention.
Now I can (a) create a person
route under people
resource to be a single state of a person record; or (b) I can create a person
resource under the people
resource, so I would have more options under person
resource (edit, detail, delete); or (c) I could create a separate resource for person, and use the path to override the url if I want to.
I sometimes go for option c:
App.Router.map(function() {
this.resource('people');
this.resource('person', {path: 'person/:person_id'}, function() {
this.route('edit');
this.route('delete');
});
});
That would make sense that edit
is route since it doesn't have child states , only siblings (delete) and a parent (person). The url for a record would be something like this: ~/#/person/3/edit
).
The routes, when not defined as a resource, won't have any child route/state, so you don't have person.edit.index like you have person.index, in other words, routes don't have child, only siblings and resources can have both.
Right now, the Routing Guide is the most solid piece of documentation we have about this. I strongly recommend it.
Dynamic Segment is a part of a route URL which changes according to the resource in use. Consider the following:
App.Router.map(function() {
this.resource('products', function() {
this.route('product', { path: ':product_id' })
}
});
In the stub above, the line:
this.resource('products', function() {
will produce the url
~/#/products
and the following line will produce
~/#/products/:product_id
replacing the dynamic part, you could have an url like this
~/#/products/3
the :product_id
is what makes this route dynamic. The router will serialize the id of a resource (for example a Product
model) to the URL and it also uses that id to find
the a model in your DS.Store
. You'll often see this in routes like the following:
App.ProductRoute = Em.Route.extend({
model: function(params) {
return App.Product.find(params.product_id);
}
});
So for this example, if you access ~/#/products/3
, the app will then try to load an instance of the Product model from your store or try to fetch from your backend API.
You can see a fiddle that illustrates that here | source here
I also recommend this screencast by Tom Dale where he builds a blog reader app with Ember.js using the router and the ember-data API to load blog records based on the dynamic part of the URL.

- 26,371
- 26
- 130
- 172

- 9,082
- 2
- 38
- 53
-
1Joe, thanks for answering so quickly! I keep on feedbacking to follow your explanation: where do the `map(..)`, `resource(..)`, and `route(..)` functions come from? I can't find them on the [`Ember.Router` API documentation](http://emberjs.com/api/classes/Ember.Router.html), where I'd expect them to be documented. – Abdull Mar 29 '13 at 18:03
-
I don't think the Router API is fully documented because it's going through some re-write if I'm not mistaken. I think you should be checking the [Guides](http://emberjs.com/guides/routing/defining-your-routes/#toc_dynamic-segments) instead – MilkyWayJoe Mar 29 '13 at 18:29
-
So to grasp the semantics of those functions I can't count on any API documentation contract currently, but instead am left with reading those function's source code?... It's not clear to me what that callback inside the callback is good for. Phew. – Abdull Mar 30 '13 at 00:22
-
1I feel your pain. This is due to the fact that Ember changed a lot during a relatively short period of time. The API will probably receive more attention before the framework is released as final. – MilkyWayJoe Mar 30 '13 at 01:28
-
We are getting closer to an accepted answer :)... With respect to [the screencast from 11:06 until 11:58](http://youtu.be/Ga99hMi7wfY?t=11m6s): For the "nested route", your provided code uses `this.route(...)`, while the screencast uses `this.resource(...)`. Is there any difference between `this.route(...)` and `this.resource(...)`? – Abdull Mar 30 '13 at 01:48
-
2For anyone curious: `App.Router.map(..)` comes from [`Ember.Router.map(..)`](https://github.com/emberjs/ember.js/blob/master/packages/ember-routing/lib/system/router.js#L235). ... `this.resource(..)` comes from [`Ember.RouterDSL.resource(..)`](https://github.com/emberjs/ember.js/blob/v1.0.0-rc.2/packages/ember-routing/lib/system/dsl.js#L12). ... `this.route(..)` comes from [`ember.RouterDSL.route(..)`](https://github.com/emberjs/ember.js/blob/v1.0.0-rc.2/packages/ember-routing/lib/system/dsl.js#L42). – Abdull Mar 31 '13 at 02:22
-
This is so WELL explained compared to what I found on the official docs. The exemples help a lot. Thanks. – Asme Just Dec 24 '13 at 18:21