Programming

EmberJS Crystalized - Part 1: Foundations

June 7, 2012
--
User avatar
Adrian Perez
@blackxored

I think Ember.js has the potential of becoming the go-to JavaScript MVC framework. The architectural decisions made, boilerplate added, auto-updating templates, a class system and property bindings make it stand above the crowd. But, speaking for me personally, it's a tricky project to get your hands on. This part will be introductory trying to build some foundation for the upcoming parts.

A Quick JavaScript MVC Refresher

If you're familiar with other JavaScript MVC frameworks (such as Backbone, which I'm a big fan of) feel free to skip to the next section.

As you might be aware by now, traditional server-side MVC as you know it, it's not easily mapable in the client-side. The interesting part of it is that the original pattern wasn't developed with the server in mind, but instead it was geared towards graphical user interface (GUI) design.

At a glance MVC/MVP/MVVM targets a separation of concerns that allows you to aim for low coupling, single responsibility, and other common standarized practices of good design. By allowing you to separate, modularize and categorize your application in distinct levels of abstraction it allows you to have a strong foundation for your forthcoming development.

A Model typically holds the business logic of the application, and mostly is mapped to the data the application manages and the operations performed on that data. Models are the least controversial side of the MV* patterns.

When it comes to the Controller it gets trickier. In the traditional server-side model (think Rails or Spring) the controller is usually the object that retrieves the Models from the datastore, checks permissions and passes data to the views. In the client-side world, however, things doesn't seem that easy. We're used to seeing classes binding a specific model to different events, fetching model collections from the related storage, rendering views, reacting to view events, and even some of them combined. In JavaScript, you have freedom where regards to controller, but several standarized patterns have started to emerge.

The View in the JavaScript world is generally mapped to the class that defines the view properties and/or events and not the view templates themselves, and by template I mean markup.

I won't be giving a MVC lesson here, if you want to read on an excellent introduction to what I briefly try to describe in here, take a look at Addy Osmany's Backbone Fundamentals.

What's Ember.JS

Ember is probably the latest JavaScript MV* framework to hit the scene. Built upon the foundations of a full Rich Internet Application framework called SproutCore, one of the main purposes of the library what's to extract common functionality that felt like could be used in other kind of applications (meaning not necessarily SproutCore apps).

What's really interesting about this, is that the aforementioned minimal functionality, actually rocks and probably gives you more than any other framework in town.

What does it mean to you as a developer

Ember use cases, such as those for any library, are not finite. I couldn't possibly predict how this can be leveraged in real life.

Ember's subjective complexity (when compared to other frameworks), at the end of the day ends up freeing your from a few interactions, (and code), that you though they were common-place.

With Ember, you don't have to bind a model collection to a view rendering, you don't need to have your controller or anything else do this for you. It just works.

Similarly, you don't have to watch over for model changes to refresh your views, it's the same than before, Ember and Handlebars have you covered.

You can compose views made of programmed or templated views, effectively enabling the practice of compositing your entire app of small views that only have one reason to change.

You won't find yourself what's the best way to manage state (that "do I put this in a model, or a generic class, or...?" moments) because it'll give you a finite state machine implementation at Ember.StateManager, whether is a generic state or a view state, one that will even have routing backed in.

Where all begins: Ember.Object

We all know by know that JavaScript lacks support for a native class system. And yet every single library in the JavaScript MVC world seems to add it's own. Why? Because it's actually needed!

At the core of the Ember framework is a little object called Ember.Object which serves as both the root for the Ember's class hierarchy and a boilerplate for building your own objects. Having stepped through a few libraries trying to do his own, like Sensha or even Spine, I've found Ember.Object pretty easy to use and also very powerful.

Don't skip this section unless you're already familiar with it, since all your Controllers, Views, Models, you name it, have its roots in here.

Yes, sure I bet you want me to elaborate on that, since "powerful" doesn't cut it. All right, the root of Ember's class hierarchy, this thing called Ember.Object is perhaps the most powerful of any other because of a few reasons outlined below:

  • Every user-defined property of the object can be bound to.
  • Every property can be used in a View that updates itself when it changes.
  • Every object has observable support. (Think pub/sub).
  • Every object trigger useful events (for example, when a value changes).
  • Every object has the ability to reopen it's definition using Ember constructs.
  • Every property of that object is cacheable (think memoized).
  • Every object can be enhanced with separate, mixin-style methods and properties (the perfect analogy for a mix-in module in Ruby).
  • A property can be marked as required so to forgive humans of making mistakes.
  • An object's property can be marked with meta-data besides the value itself.

Just to name a few.

Creating an Object

So, Hello world style, how do you create one of them?

puppy = Ember.Object.create({
  name: "Gooffy",
})

That's all there's to it. For the sake of the post, we will assume we've actually created a namespace in the following manner:

App = Ember.Application.create()

App.puppy = Ember.Object.create({
  name: "Goofy"
});

But what does it gives us? As I said above there are lots of benefits of using Ember.Object instead of a plain JavaScript object (there's also an overhead included, things are not 100% free).

Getting and Setting Properties

I've found out to be only two preferred ways of getting and settings properties, and in my testing you shouldn't access the property directly, but many other libraries enforce this conversion, so Ember wouldn't be much different.

  var get = Ember.get,
      set = Ember.set;

  // First mode (which I prefer since it seems a little more OO to me):
  App.puppy.get('name')                    // #=> returns "Gooffy"

  // Second mode (really great when you must be dynamic):
  get(App.puppy, 'name')                   // #=> also returns "Gooffy"

Binding Properties

This are is where Ember really shines. I could put a binding into a property, and when the property changes it'll be automatically updated.

Let's say our puppy from the example below has an owner. I bet you didn't see that coming. ;)

Here, we will replace the puppy object just created to add a binding for the owner's name, ownerName property.

App.owner = Ember.Object.create({
  name: "Clark"  
});

App.puppy = Ember.Object.create({
  name: "Gooffy",
  ownerNameBinding: "App.owner.name"
});

App.puppy.get('ownerName');              // returns Clark
App.owner.set('name', 'Bob');            // change the owner's name in the owner object
App.puppy.get('ownerName');              // returns Bob

Trust me, this will change the way you program.

Conclusion

In the next part let's examine the different options for getting you started with Ember.JS, including Ember Skeleton and the Ember starter kit.

~ EOF ~

Craftmanship Journey
λ
Software Engineering Blog

Stay in Touch


© 2020 Adrian Perez