5 Useful Tips for Ember.js Developers

Ember.js is growing and growing fast. As with any new technology, once you want to do something that is not covered in the guides, you are gonna have a... google time.

Here are 5 things that I learned while building a real world application with Ember.js. Hope they will save you some time!

Sorting an ArrayController

Add sortProperties and sortAscending to the controller:

App.RecordsIndexController = Ember.ArrayController.extend
  sortProperties: ['id']
  sortAscending: false

Then, in your template:

{{#each controller}}
  <article class="record">
    {{text}}
  </article>
{{/each}}

You can still get the non-sorted array by using {{#each content}}.

Metamorphs breaking :last-child CSS selectors

A template like this:

{{#each arrangedContent}}
  <article class="record">
    {{text}}
  </article>
{{/each}}

produces html like this:

<script id="metamorph-7-start" type="text/x-placeholder"></script>
<article class="record">...</article>
<script id="metamorph-7-end" type="text/x-placeholder"></script>

Of course, it breaks your :last-child CSS selectors. The solution is to use the :last-of-type selector:

.record
  border-bottom: 1px solid #eaeaea
  &:last-of-type
    border: 0

According to developer.mozilla.org, :last-of-type is supported in all major browsers. Surprisingly, it also works in IE6! Actually, it does not, and I'm just beating the dead horse here.

Using jQuery.timeago plugin Ember.js

To use the timeago plugin with Ember, you'll need to create a TimeAgoView:

App.TimeagoView = Ember.View.extend
  tagName: 'abbr'
  classNames: ['timeago']
  attributeBindings: ['title']
  title: null

  didInsertElement: ->
    @.$().timeago()

You can then use it in the template, passing the date in titleBinding.

<article class="record">
  {{text}}
  {{view App.TimeagoView titleBinding="createdAt"}}
</article>

Toggling properties

Imagine that you have a template for a blog post with comments. You want your users to be able to show and hide the comments section.

Your first instinct might be to create showComments and hideComments actions in the controller, but there is a much shorter path (and that's why I love Ember.js, its core team "gets it").

Here's how you can do it:

App.PostShowController = Ember.ObjectController.extend
  showComments: false
<article class="post">
{{text}}

<button {{action toggleProperty "showComments"}}>Toggle Comments</button>
{{#if showComments}}
  <!-- show comments here -->
{{/if}
</article>

Even though our PostShowController does not have a toggleProperty method, it will work because Ember.ObjectController extends Ember.Observable which has the toggleProperty method.

This works with simple a Ember.Object as well.

Integrating Ember.js with Devise

I originally planned on posting this as a tip but it got big enough for its own article. You can read it here: Using Rails & Devise with Ember.js.

You're the 23406th person to read this article.