Reversing the output of an Ember.js content array

Filed under: Ember.js

comments (2) Views: 8,743

Today I was talking to a coworker about Ember.js and I made the analogy that for me Ember is to MVC what jQuery was to JavScript. That is to say that when I started learning jQuery about 6 years ago I was a novice at JavaScript. jQuery has helped me to become a better JavaScript developer. In the same way, Ember is helping me learn and understand MVC frameworks in a way that I haven't been able to do for years. In this blog post I'm going to show how simple it is to bind an array to a bulleted list using Ember, but display it in descending order instead of in traditional ascending.

One of the great things about Ember is it's data-bindings. They allow developers to focus on content without worrying if everything on the page is updated correctly. Ember has a contstruct called an ArrayController which provides an internal dataset for use as in memory data storage. When a visual element (a view) is bound to this content array Ember outputs the data in ascending order: 1, 2, 3. In an app I'm building I wanted to display the last item (the most recently inserted) first or 3, 2, 1. With some help on Stack Overflow, this is the result. Let's look at our view first.

Application HTML

Within your HTML page, every view must be contained within a script block with a type of text/x-handlebars. This tells Ember that this is a block which should be parsed. The first line points to a view...in this case a text input field which will be created in our JavaScript file, but more on that later. The contents of the #each block will be output to the page, once for each item in the content array.

The minimum requirement for an each block is that you feed it a set of data: in this case that's App.recentUsersArray.reverse. This value is basically the "path" to the data source. App is the namespace of our Ember application, recentUsersArray is the object containing the data we want to display. In most cases that's where you'd stop, but because we want to reverse our dataset, we reference a property contained within recentUsersArray. Finally Ember allows you to create your container tag by passing a tagName. Since we're displaying a bulleted list, we're using tagName="ul". Next, let's take a look at the app code.

Application Creation

The first thing that you should do in any Ember application is to define a namespace/application. This serves several purposes. It acts as a "container" for the rest of your application variables, also called a namespace. Second, it provides important properties and functions. The only requirement is that the variable containing your application must be uppercase.

View Creation

Views can be created in several manners. If need be, you can create a view completely within your HTML file. This works for very simple views, but when you want to add functions you'll need to define it in code. Notice that our view extends Ember.TextField, and is assigned to a variable within App. Extending an object essentially means you're making a copy of an item that already exists. Just like in our app creation, this means that we get all the goodies already contained within that master object. In the case of TextField a function named insertNewline becomes available to us. This is a helpful function that is triggered whenever a user hits the Enter key within the TextField.

The contents of the insertNewline function do the work of inserting the term we just submitted into the content array of our data storage object, App.recentUsersArray. One thing about Ember that took some getting used to is the way that it obtains values. Because of the way that it was built every Ember element contains a get, and a set function. This allows you to easily target an item and interact with it. You can get and set values, or even call functions. Because we're working within the context of the TextField view we use this to refer to the text field. The get method simply takes the name of the property we'd like to access.

Just like the Application gets cool stuff baked in, other Ember elements get them too. In this case we can add items to our ArrayController by using a built-in method called pushObject. It takes a simple, or complex, value and adds it to the content array. Nice and easy! Pass the value we retrieved from the text field and we're done.

Controller Creation

The ArrayController contains our data. Here we've created a copy of an ArrayController and again have placed it in the namespace of our App. We're seeding the content array with a commadelimited list of values. They can be string values or complex values, whatever you like. It can also be empty.
Use "Em" as a shortcut to creating Ember items. Em.ArrayController and Ember.ArrayController are the same thing!

In our view we referenced App.recentUsersArray.reverse which refers to the reverse method you see above. Even though this is a function, Ember allows us to treat it as a property (or simple value) by tacking on .property(). Ember calls any function using this a computed property and it allows developers to do some awesome stuff. Computed properties require that you reference any value used in the function. This tells Ember to manage bindings for that value. In this case content is the variable, and the @each tells Ember that it needs to manage each item in the content array. Lastly we're tacking on the .cacheable() method which tells Ember to cache the returned value of the reverse function until it changes.

Like many functions reverse returns a value. In this case the function first gets the required data store using our trusty .get() method. Because Ember stores data in a form that's like an array (but not quite) we convert it to a "real" array by using the built-in .toArray() method. Then finally we call the vanilla array method "reverse".

You can see a running example of the code we just reviewed over at JSFiddle.

Hope this helps someone get a better understanding of Ember and encourage them to check it out and start using it.

Amazon logo

If this article was interesting, or helpful, or even wrong, please consider leaving a comment, or buying something from my wishlist. It's appreciated!

Related Posts


comments powered by Disqus