Apr 20, 2015
Table of contents:
URLs are very important in just about every type of web application. A well designed URL scheme should describe the user’s location within the hierarchy of the application.
In a modern web application, the user should be able to navigate by either taking an action through the user interface, using a browser function or typing the URL directly. Traditionally this has not always been easy in Javascript heavy client-side applications.
Ember has an excellent router that abstracts this complexity to provide you with an easy to use interface.
In today’s tutorial we are going to be looking at the Ember router.
Before we get into today’s tutorial, the first thing you should do is install the Ember Inspector.
The Ember Inspect allows you to see all of the routes that are defined in your application, information about the templates, controllers and models, inspect the objects of your application, plus much, much more.
You will also want to add the LOG_TRANSITIONS
property:
var App = Ember.Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
Resolver: Resolver,
LOG_TRANSITIONS: true,
});
Now when you move between pages of your application you will see helpful debug information in the console.
In an Ember application, the router is very important. The router is responsible for displaying templates, loading data and setting up the application state.
In order for Ember to know about the routes of our application, we need to first define them in the routes.js
file:
Router.map(function () {});
If you’ve been following a long with the last couple of articles, you will know that we were able to hit the /
route without it being defined. This is one of the default routes of an Ember application, so you don’t need to define it.
To define a new route in our application, we can simply call the route()
method inside the map()
method of the Router
and pass the name of our desired route:
Router.map(function () {
this.route("contact");
});
This will created a named route called contact
. By default this will route to the /contact
URL.
If you want to override this default URL to provide a different URL, you can do so by passing an optional second object parameter:
Router.map(function() {
this.route('contact', {path:'/contact-us'});
});
In last week’s tutorial we looked at using the link-to
View helper.
To use our new contact
route in a View we can write the following in the template:
{{#link-to 'contact'}}Contact{{/link-to}}
This will generate the following HTML:
<a href="/contact">Contact</a>
Ember applications have the idea of routes and resources.
As we’ve just seen above, a route is just a single URL. A resource is a collection of routes that describe a resource of the application.
For example, in Cribbb, we might have the following resource:
App.Router.map(function () {
this.resource("posts", { path: "/posts" }, function () {
this.route("new");
});
});
The nested new
route would resolve as /posts/new
.
You can also have multiple levels of route nesting:
App.Router.map(function () {
this.resource("post", { path: "/post/:post_id" }, function () {
this.route("edit");
this.resource("comments", function () {
this.route("new");
});
});
});
When you want to access a single item of a resource through the URL, you typically pass the id
as a parameter along the lines of /posts/123
where 123
is the id
.
You would define a route with a dynamic segment like this:
App.Router.map(function () {
this.resource("posts");
this.resource("post", { path: "/post/:post_id" });
});
This is such a common pattern in web applications that Ember will automatically know to find the post with the id
that was passed in through the URL.
One of the best things about Ember is that it follows a Convention over Configuration policy. This means if you follow the naming conventions that are already established, things will just automatically work.
A good example of this convention can be seen when defining routes.
If you define a route named post
, Ember will automatically make the following assumptions:
/post
PostController
PostRoute
post
This can seem restrictive at first, but honestly convention over configuration is a much better approach. When developing a web application you have to make a million decisions, you shouldn’t have to think about wiring up these components.
If you would like to customise the behaviour of a route you can create a new Ember.Route
object:
App.PostRoute = Ember.Route.extend({});
As I mentioned above, due to the naming conventions of Ember, the application will automatically know to use this class for the post
route.
We will be looking into this more in next week’s tutorial.
Routing requests through your application is common to all web applications. The job of the framework is to deal with this boilerplate complexity so you can get on with working on your application.
Ember’s Router is easy to use and understand. What’s more, if your application follows many of the common standards of a modern web application, the majority of the functionality should work straight out of the box.
This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.