The Basic Anatomy of an Ember Application


There are a lot of different aspects of Ember, the JavaScript “framework for creating ambitious web applications,” that you’ll need to understand before you really feel a sense of mastery. But the most fundamental and useful by far is to get the basic understanding of the shape of an app. They have a few core units that you’ll want to understand, and you can mostly work out the details from there.

If you’ve been a web programmer for some time, some of the anatomical units are probably pretty familiar to you. Actually most of them probably are, which is one of Ember’s best qualities. If its core architecture is familiar and comfortable to you, you can move around Ember projects simply because they’re all likely to use these same core units. But whether you’re new to each and every unit we’ll quickly summarize here, or an old hand at these concepts but new to Ember, I’m pretty sure you’ll learn something.

The Application’s Map: The Router

Like most other web MVC frameworks in the world, all Ember requests go to a front controller which is in charge of route matching and dispatch into the rest of the application. Yep, even though Ember is a JavaScript framework, it treats URLs as both important and fundamental to what it’s doing. Essentially in Ember you declare your routes and those names are used to find your actual individual route declarations which cascade down into the rest of the app.

A router declaration will look something like:

App.Router.map(function() {
  this.resource('post', { path: '/post/:post_id' });
})

Data Preperation: Routes & Models

One of the big things that differentiates Ember’s “MVC” from a more traditional server-side web MVC frameworks (i.e. Ruby on Rails, Symfony, Laravel, etc) is that the router doesn’t match to directly or exclusively map to a controller method. Rather, based on the match found at the router, Ember dispatches to a route whose primary charge is to load up the the model for the final page. What exactly this looks like can vary substantially, mostly based on whether or not the Ember app is using the optional Ember Data library — which I appreciate, but is completely optional.

A basic route (using Ember Data) looks like:

App.PostRoute = Ember.Route.extend({
  model: function(params) {
    return this.store.find('post', params.post_id);
  }
});

The important thing to understand about your route declarations is that the model is what is interacted with by a controller and viewed in your final rendered view template. It can be an array of objects, a single solitary piece of data, or anything in between. But the route’s most important role is to get and prepare that data, everything else just augments that.

Models themselves, if using Ember Data, are a defined list of properties parsed and automatically saved to an endpoint. If you don’t use it, yours can simply be pulled to your application in your routes and have no external definition.

How We Interact: Controllers

Controllers in Ember have two basic uses: they can enhance or transform the model, and they can respond to actions taken by users on the final rendered page. Transformation of properties is just done with new properties on your controller, these are available to your view and template.

The responding to actions is so primary that your controller’s most defining feature is likely to end up being your actions hash, which does essentially what you’d expect: corral all of the functions on your controller that respond to actions in the rendered page into a single place that you or someone else would expect to look for them.

A somewhat contrived controller example:

App.PostController = Ember.ObjectController.extend({
  length: function() {
    return this.get('model.body.length');
  }.property('model.body')

  actions: {
    favoritePost: function() {
      // logic goes here
    }
  }
});

Let’s See It: Views & Templates

Essentially, from the declared route you’ll get a view and template. Practically speaking, if you’re writing a template in Ember, you’re using Handlebars. Personally, I mostly like Handlebars syntax. Lots and lots of curly braces, but they end up pretty simple to both read and write.

Here’s a quite simple Handlebars template:

<h2>{{title}}</h2>

{{body}}

Views are something you won’t necessarily have a lot. You’ll use them to declare CSS classes and other variables that may be relevant to your template. You’ll use them to specify the template, if it’s different than what Ember guesses it would be. But again, they’ll typically be pretty thin and devoid of complex logic, which is a good thing.

And a view might looks as simple as:

App.PostView = Ember.View.extend({
  classNames: ['post-view']
});

How All The Parts of an Ember App Tie Together

One of the most interesting facets of Ember is that that from top to bottom, you don’t have to explicitly create all these units. When you don’t and they’re needed, Ember will just automatically create them for you.

One of the most interesting facets of Ember is that that from top to bottom, you don’t have to explicitly create all these units. When you don’t and they’re needed, Ember will just automatically create them for you. So if you don’t need to specify anything unique between your controller and your template, there’s no need for you to create a view for that specific route, it’ll just get auto-generated with the basic behavior you’d expect. Same goes for a controller where you don’t actually need to have any interactions or model-augmentation.

So for example, in our code samples we could easily omit the declarations of PostView entirely. Or if we didn’t actually need the length property in our template — we didn’t use it after all — and especially if we never got around to implementing that favoritePost stub, we could drop the controller too.

This kind of auto-wiring is one of the best and worst aspects of working with Ember, in my experience. The bad: it can be a bit too magical that things work before you understand all the bits that are going into it, so it can be a bit of stair-stepped learning curve in Ember.

But, once you get it, and if it works with your way of thinking about your application, it’s a huge boon to your productivity and need to create boilerplate wiring logic that does little. You simply write the parts you want, name them in the way Ember expects, and your app just works.

We’ve only touched the core necessary units of an Ember application, there’s a lot more concepts and ideas to Ember that you should learn about in time: mixins, components, computed properties, Ember Data, Ember CLI, Ember Inspector, and the Ember object model, all just come to mind rather immediately. But I think they’re all a bit more than we should jump into right away; this is enough that you should be able to walk into an Ember app and feel a bit more ready to have an impact. Happy hacking!

Image Credits: tiffany terry

About David Hayes

David likes learning, solving hard problems, and teaching. He bikes a lot, and lives in (and loves) Colorado. You can find him on Twitter as @davidbhayes and check out his latest hobby-project, Quodid, a monument to his love for pithy bits of wisdom.

1 thought on “The Basic Anatomy of an Ember Application

  1. Pingback: Javascript Weekly No.204 | ENUE

Leave a Reply

Your email address will not be published. Required fields are marked *