Getting Started With EmberJS
comments (57) Views: 78,942
I consider myself a pretty good developer...by no means the best, but I'm skilled at taking existing technologies and forging them into something unique and of my own creation. I've been eyeing these frameworks for a while now and for my needs it's come down to Backbone, and Ember. I've done research on Backbone, even purchasing a Backbone video tutorial. It's nice, but still seems hard to wrap my head around. I started hearing about Ember just a few months ago, and already it's gaining traction. It offers many features that appeal to me and so I decided to dive in and see how it fits me. Ember offers several key pieces of functionality that I find very appealing, chief of which is data binding. This simply means that you can create a variable, then tell Ember that when that variable changes, update any part of your application which watches that variable. Think a stock ticker, real time chat, etc.
One of the drawbacks of Ember over Backbone is that the latter has a wealth of tutorials, articles, and Github projects while the former has very little available material. What IS out there tends to give a very shallow coverage of the basics, then dive straight in to the in depth stuff, the parts that only people who've been using it for a while understand. So it's my goal to write a bare bones, basic Ember tutorial that will cover the parts that many people tend to leave out. I'm also writing this article to help cement my own understanding of these concepts.
Ember.js is an MVC (or Model View Controller) style framework which simply means that it offers you the ability to break out your code into 3 distinct types of pieces.
- M = Model - The Model is like a cookie jar. It's where your data is stored while waiting to be used by the app.
- V = View - The View is the visual aspect of your app. It's a form your users interact with to input information, it's a list of data they can select from, etc.
- C = Controller - Think of the Controller as the traffic cop. It manages the interactions between the other parts of your application. When someone clicks a button, the Controller decides what View should be loaded, which in turn determines what Model is used to populate the information.
Let's get started shall we? First things first, go ahead and download the Ember.js starter kit. Unzip it and dump it into a directory that's web accessible. Open index.html and js/app.js in the text editor of your choice. Within app.js, add the following line.
Congratulations! You just created your first Ember application! Load index.html in your browser and glory in the website you just created. Oh wait, there's nothing there...what do you think this is? Ruby on Rails? Nothing shows up, except for the title, and that's perfectly fine. All that's going on is that behind the scenes Ember has created an application for you that you'll reference throughout the rest of the tutorial. You may see other developers refer to the Application as a Namespace. This simply means that all the other parts of your app will start with the name you selected. This helps avoid variable collisions and keeps everything neat and tidy.
One thing that most jQuery developers are used to is our old faithful document.ready block. Ember offers something similar by passing in an optional object to the create method. Add the code below, reload your page and you should get an congratulatory alert. Pat yourself on the back...you deserve it.
The next thing we need to do is to add our data, or Model. Each Ember application can have multiple Models, each "Modeling" a unique type of data. In some languages a Model is the same thing as a class. It's basically a blueprint for how to refer to this object. Let's create a model for some of my favorite books.
The next thing we need is a Controller. In addition to controlling traffic, Controllers in Ember also funnel data to the View from the Model. Here's a simple Ember Controller.
Implicit in the creation of an Ember ArrayController is a content array. This is where the information about our books will be stored. It's there, you just can't see it. If you want to though, you can explicitly create the content array, perhaps you wish to prepopulate it. That's accomplished by passing an optional object to the create method, just like we did with the Application.
Now that we have a Model and a Controller, we need a View. Remember that the View is the part users will see, so that's going to be part of the HTML file so switch over to index.html. Let's add our view, then discuss it. Directly below the H1 tag, add the following code.
One of the great things about Ember is that it ships with a built in templating engine called Handlebars, in fact templates are a key piece of Ember's magic. In general templates work by wrapping the variable pieces of your code with some string. With Handlebars it's a curly brace, and not just one, but two of them. Turn your head sideways and you'll see why they call them Handlebars pard'ner.
Ember started it's life as a library called SproutCore, developed by Apple as the "core" of it's online applications like Mobile Me. SproutCore also included UI widgets which Ember does not...sort of. Ember has built-in views for form elements because those can be highly dynamic. In the case of our template, or View, we're using an Ember button. This allows Ember to do all of the grunt work for us. It takes a target, our bookController, and an action. So when someone clicks the button, it will run the loadBooks function of the Welcome.bookController. See how it all fits together?
The second chunk is a little more complicated, but I know you'll get it. Your mother always said you just needed to apply yourself. In Ember, a collection is simply a pointer to a grouping of data, in our case it's the Welcome.bookController object again. I mentioned that data binding is one of the reasons I'm interested in Ember, and we can see it's power here. Content simply points to the content variable in our bookController, while the Binding portion of it is the magic dust. Adding Binding to the end of most attributes tells Ember that you want to initiate a two way binding. Change the information on one side and the other will update. Lastly the collection allows you set a base tag, in our case it's a plain bulleted list.
By the way, the # and / symbols are merely there to tell Handlebars that this particular View has a closing part.
Inside the collection is the meat of our template. Notice how we're mixing HTML tags right in the middle of our template. Nice eh? Another nicety that Ember offers is that we don't have to explicitly add the opening, or closing, list item tags. It appears to add it automatically because it knows we're using a bulleted list. Running the app now and you should see a lonely button who needs friends. Clicking the button would make him unhappy because at the moment there is no "loadBooks" method. How about we add that...and some data while we're at it.
Remember when we said that Models can contain arbitrary functions? Well everything in Ember can contain custom code, including ArrayControllers. Let's add the loadBooks function, as you see it above. Now, when you load your page, and click the "Load Books" button you application should jump into action and load in the list of some of my favorite books. You care, I know you do. That's about it for this simple example. I hope you enjoyed it, and will consider giving Ember a try. You can download the complete source code on Github.
Wait, wait, wait. If you're like me you've got questions. Lots of questions. I wrote this blog post because I had questions that took me hours to find the answers to. In fact, most of the questions I had, I answered in this post. If you've questions that haven't yet been answered feel free to post them here. If I don't know the answer (which is likely), I'll find out and reply.
Make sure to check out my much longer and more in-depth article on Ember.js over at Adobe's Devnet.
If this article was interesting, or helpful, or even wrong, please consider leaving a comment, or buying something from my wishlist. It's appreciated!