Close
Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

LABS
Ember vs Angular – Templates

Over the last couple of weeks I’ve been fortunate enough to play around in both Ember and Angular. Having spent the last 18 months on an Ember project I’m very much in the Ember camp and was really rooting for Ember to end up the heavy weight champ. However what I found was that I’d be happy to work in either framework and believe that both have reached a maturity level that allows developers to think about solving high level problems instead of building glue (most of the time…). With the niceties out of the way lets get dirty and compare some of the differences in each framework. In this post we’ll look at templates.

My least favourite part in Angular is their templating syntax. Angular uses plain HTML with custom DOM attributes attributes for control flow (ng-hide, ng-show, ng-repeat). Whereas Ember uses Handlebars which supports more familiar control flow statements (if, else, each). Personally I prefer the Ember approach as it’s similar to most templating languages I have used (erb, haml, etc) and it’s easier for my CPU (aka brain) to scan and parse.

Lets look at a couple of examples.

Hide & Show

Let’s say I have a button that toggles the sort order of a list. When the list is sorted in ascending order it shows a “^” character and when it’s sorted in descending order it shows a “∨” character.

In Angular I could use the ng-show property along with a boolean operator!

<button>
   <span ng-show="sortAscending">^</span>
   <span ng-show="!sortAscending">∨</span>
</button>

Developers that like a little less logic in their templates could use ng-show & ng-hide instead.

<button>
   <span ng-show="sortAscending">^</span>
   <span ng-hide="sortAscending">∨</span>
</button>

In Ember you can use an if-else statement within your Handlebars template

<button>
  {{#if sortAscending}}
    ^
  {{else}}
    ∨
  {{/if}}
</button>

Or for those that like the pain you could use unless-else

<button>
  {{#unless sortAscending}}
    ∨
  {{else}}
    ^
  {{/if}}
</button>

There are a couple of things I don’t like about the Angular approach above

  1. Angular forces me to do mental arithmetic with hide & show. Does a truthy value to ng-hide, show or hide the span? What about the inverse?
  2. Angular leaves both the hidden and displayed span in the DOM and assigns a display: none style attribute to the element that should be hidden. When I look at the DOM in Chrome inspector I prefer my DOM to be a reflection of what I see on the screen. When Ember sets up the if-else block it watches that property and adds/removes the block from the DOM that doesn’t need to be displayed.
  3. When building a toggle control like the one above I need to either repeat the <button> or the <span> in Angular. Ember lets me switch the content of my button without repeating myself.
  4. The Ember code almost reads like a sentence. I read the first Ember example as:
    If sortAscending is true then show an up arrow else show a down arrowThe Angular code doesn’t read like a sentence. I have to put in some effort to deconstruct each ng-show/ng-hide attribute and re-arrange the code as words in my sentence. It might go something like:
    Show the first span when sortAscending is true

    Don't show the second span when sortAscending is true

Where’s The Logic?

Keeping logic out of the view is one of the best practices preached by many a framework these days. Angular is no different. In the Angular documentation it states:

application logic should be in controllers, not in the view

I don’t see this throughout their template design. Angular attributes can take complex expressions or filters. This makes quickly wiring up complex UI interactions a snap but a pain to test. If a development team doesn’t know better, or try to enforce best practices, it’s very easy to write code like this:

<div ng-show="people.length>100 && user.isFree">
  You've got too many friends
</div>

Following Angular best practices would yield something like this.

<div ng-show="hasTooManyFriends()">
  You've got too many friends
</div>

Handlebars only allows boolean logic within their control flow constructs. Meaning we would have to follow the same best practices Angular preaches.

{{#if hasTooManyFriends}}
  You've got too many friends
{{/if}}

Enumeration

At the moment enumeration in Angular works for most cases. However there are currently a couple of uses cases that cause it to fall over. To render a list of people I can use the ng-repeat attribute on an element.

<div ng-repeat="person in registrations">
  Hi I'm {{person.firstName}} {{person.lastName}}
</div>

I think the core team have really nailed rendering lists in Ember. Lets take a look at some of their tasty syntax sugar by using the each construct.

{{#each person in registrations}}
  Hi I'm {{person.firstName}} {{person.lastName}}
{{/each}}

Did you notice that Angular requires a wrapper element to repeat? Now don’t get me wrong most of the time you’re probably going to want an element to wrap your item’s content. The gripe I have here is that Angular forces me to always wrap the content I want to repeat in only 1 element.

Lets look at a more complicated example. This one’s straight out of the Ember vs Angular cage match that has been doing the rounds. My feature calls for me to render a set of tabular data for each person that has registered for one of my special offers. However our designer has thrown us a bit of a curveball. She want’s the persons name on one row and all of their meta information (age, sex, etc) on a second row.

In Angular I can’t repeat two <tr> elements. I’m going to have to add some extra wrapper tags within my row.

<table>
  <tr ng-repeat="person in registrations">
    <div>{{person.firstName}} {{person.lastName}}</div>
    <div>{{person.age}}, {{person.sex}}</div>
  </tr>
</table>

In Ember I’d use the familiar each construct as it repeats everything in the provided block.

<table>
  {{#each person in registrations}}
    <tr>{{person.firstName}} {{person.lastName}}</tr>
    <tr>{{person.age}}, {{person.sex}}</tr>
  {{/each}}
</table>

There is some work being done to rectify this problem in future releases of Angular. However as you can probably tell I’m not really a fan of the proposed solution that uses ng-repeat-start & ng-repeat-end. How would I repeat 3 rows?

To finish up enumeration lets notify the user that no one has signed up yet. We can keep building on our existing example. To display the empty message in Angular we’re going to need to bring back ng-hide from earlier.

<table>
  <tr ng-repeat="person in registrations">
    <div>{{person.firstName}} {{person.lastName}}</div>
    <div>{{person.age}}, {{person.sex}}</div>
  </tr>
  <tr ng-hide="registrations.length">
    It sucks that no one's signed up yet. Check back later eh.
  </tr>
</table>

Lets add to our existing Ember example by using the handy else case in conjunction with each

<table>
  {{#each person in registrations}}
    <tr>{{person.firstName}} {{person.lastName}}</tr>
    <tr>{{person.age}}, {{person.sex}}</tr>
  {{else}}
    <tr>It sucks that no one's signed up yet. Check back later eh.</tr>
  {{/each}}
</table>

I prefer the Ember approach for a couple of reasons.

  1. I can scan the Handlebars template where the else sticks out which clearly indicates it's doing something different in the enumeration.
  2. The extra row in Angular doesn't immediately stick out. I have to look within the extra <tr> to notice the ng-hide attribute. Not to mention I now need to coalesce the number of registrations into a boolean check for ng-hide

Attribute Bindings

Lets say I have an element and I want to be able to toggle whether or not I can edit it. Something as simple as setting contenteditable="true" on a <div>. Angular has a really nice and concise syntax to achieve this.

<div contenteditable="{{canEdit}}">Edit me!</div>

Ember on the other hand leaves a lot to be desired. Attribute bindings have their own special syntax which is different to content bindings.

<div {{bindAttr contenteditable="canEdit"}}>Edit me!</div>

It's worth noting that work is currently being done to bring Ember in line with Angular in this department. It's slated to drop in Ember 1.1 which at the time of writing has no public release date.

That's all folks. Hopefully you found some of the differences useful. Either way let me know which style you prefer and why in the comments or hit me up on twitter @rupurt

Comments
  1. Ricky says:

    hi, i like your post! I learning AngularJS and I was looking for some way to manage enumeration and solved it with the directives ngHide and ngShow but i do not like at all.

  2. joaozito polo says:

    Hi!

    This first representation of “order” can be make using a function, or waiting for new version of angularjs, which allow ternary expressions (this new version is RC now)

    example on jsfiddle:
    http://jsfiddle.net/joaozitopolo/UfwPC/

  3. In the code examples for Ember, JSON values are being provided by Ember models but Handlebars provides the display logic.

    In the case of Angular, display logic is generally based on data within models that are bi-directionally bound to HTML, meaning that changes in HTML elements automatically updates models and vise-versa.

    That said, if a developer prefers to see display logic within templates using Angular, expressions can be used for most Angular directives.

    Here are some examples:


    Happy Kitten


    Happy Kitten

    Hope that helps.

  4. Fredrik says:

    I’m just learning about front end frameworks. But I think that angular have the better situation when combined with back end templating engines such as Jade.

  5. Oscar says:

    Very good sir. I was looking for something as objective as this.
    Thanks.

  6. Hansen says:

    I like Ember – its awesome!

  7. john moon says:

    Great article Alex! I know this is scratching the surface of the two but I do like the comparisons of syntax and their fundamental build.

    Have any suggestions or directions who wants to learn Ember, for someone with a Ruby on Rails background, but who barely touched javascript?

  8. Alex Kwiatkowski says:

    Hi John,

    I really liked https://github.com/emberjs/ember-rails which provides a familiar directory structure, generators, active model serializers and server side handlebars compilation. However a lot of the cool kids are moving to ember app kit and https://github.com/dockyard/ember-appkit-rails which are more actively developed and provide support for ES 6 modules.

  9. Alex says:

    Hello,

    Nice article. I just had to comment that I think that the Angular way of doing it is better: It takes advantage of the DOM. Ember uses comments for logic (which is similar to server-side templating). It makes sense for server side templating languages to use things that aren’t DOM elements, because they have no concept of the DOM (just really text…)

    Maybe it is easier to read for you, but the whole ember microtemplating through comments can lead to bad spaghetti code, where Angular forces them on an element — the template MUST align with the DOM.

    Why not take advantage of the DOM for templating if it’s already parsed for your MVC library to use?

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *