Getting started

with Ember.js

Erik Bryn (@ebryn)

erikbryn.com

Who am I?

I'm Erik Bryn

aka ebryn

Ember Core Team member

I consulted at Square for a year helping them build their Ember application

I now work at Tilde

We do consulting and are working on a product. Stay tuned.

Been contributing to Ember since the beginning

I'm here because I want to improve your lives

and to see this cutie

It's been a long road

The first commit to Ember was on 4/30/2011

There has been a lot of churn over the last couple years

We're finally here!

1.0 RC was released at EmberCamp

The API churn has ended

You kids today have it easy

Getting started

The amount of code it takes to get up and running with Ember can easily fit on a slide


<!DOCTYPE html>
<html>
<body>
  <script src="jquery.js"></script>
  <script src="handlebars.js"></script>
  <script src="ember.js"></script>

  <script type="text/x-handlebars">
    Hello World!
  </script>

  <script>
    App = Ember.Application.create();
  </script>
</body>
</html>
          

OK, great, now let's make it do something

Todos app!

Todos app!

Tilde Weight Tracker™

(this is not our product)

Ember 1.0

Focused on simplicity

Templates

Application template


<script type="text/x-handlebars" data-template-name="application">
  <h2>Tilde Weight Tracker™</h2>
</script>
            

The chrome of your app

Outlet


<script type="text/x-handlebars" data-template-name="application">
  <h2>Tilde Weight Tracker™</h2>
  {{outlet}}
</script>
            

Outlets are like yield's in Rails templates

Index

Index template


<script type="text/x-handlebars" data-template-name="index">
  <table>
    <thead><tr><th>Name</th><th>Goal</th><th>Current Weight</th></tr></thead>
    <tbody>
      {{#each controller}}
        <tr><td>{{name}}</td><td>{{goal}}</td><td>{{lastWeight}}</td></tr>
      {{/each}}
    </tbody>
  </table>
</script>
            

Adding a weigh in

Create template


<script type="text/x-handlebars" data-template-name="create">
  Weigh in:
  {{view Ember.Select
           contentBinding="controller"
           optionLabelPath="content.name"
           selectionBinding="selectedEmployee"}}
  {{view Ember.TextField valueBinding="newWeight"}}
  <button {{action save}}>Save</button>
</script>
            

So how do we get from the index
to the create template?

linkTo

Index template


<script type="text/x-handlebars" data-template-name="index">
  <p>{{#linkTo "create"}}Create weigh in{{/linkTo}}</p>

  ...

</script>

          

Connecting the pieces

Enter the router

Router


App.Router.map(function() {
  this.route("create");
});
          

It's that easy

How about model data?

Ember Data to the rescue

Defining our models


App.Employee = DS.Model.extend({
  name: DS.attr('string'),
  goal: DS.attr('number'),
  weighIns: DS.hasMany('App.WeighIn')
});

App.WeighIn = DS.Model.extend({
  weight: DS.attr('number')
});
          

Fixtures

Prototyping has never been so easy


App.Employee.FIXTURES = [
  {id: 1, name: 'Erik', goal: 185},
  {id: 2, name: 'Carl', goal: 175},
  {id: 3, name: 'Tom',  goal: 185}
];
          

Wiring up the data

Define our routes


App.ApplicationRoute = Ember.Route.extend({
  model: function() {
    return App.Employee.find();
  }
});

App.IndexRoute = Ember.Route.extend({
  model: function() { return this.modelFor('application'); }
});

App.CreateRoute = Ember.Route.extend({
  model: function() { return this.modelFor('application'); }
});
          

Saving a weigh in

Saving

Add a create controller


App.CreateController = Ember.ArrayController.extend({
  save: function() {
    this.get("selectedEmployee.weighIns").createRecord({
      weight: this.get("newWeight")
    });
    this.setProperties({newWeight: null, selectedEmployee: null});

    this.transitionTo('index');
  }
});
          

One more thing...

We need a computed property


App.Employee = DS.Model.extend({
  name: DS.attr('string'),
  goal: DS.attr('number'),
  weighIns: DS.hasMany('App.WeighIn'),

  lastWeight: function() {
    return this.get('weighIns.lastObject.weight');
  }.property('weighIns.lastObject')
});
          

Let's see it in action...

Thanks!

@ebryn

erik@erikbryn.com

Q&A