Your browser doesn’t support the features needed to display this presentation.

A simplified version of this presentation follows.

For the best experience, please use one of the following browsers:

An Introduction to EmberJS


Tech Camp Memphis

11/7/2015

@joshwlewis - @heroku


joshwlewis.com/slides/emberjs

Tech Camp 2014


meowmeow.joshwlewis.com

Yeah, that's cool...



...for 2012

The framework for ambitious web applications

Convention over Configuration

Ember.js is opionated....

...or maybe we could call it curated.

Conventions for

Developer Happiness

Some other great stuff

Ember is a giant toolbox

Tech Camp 2015


embeenz.joshwlewis.com

Router

Responsible for mapping paths to your code.

// app/router.js
import Ember from 'ember';
import config from './config/environment';

var Router = Ember.Router.extend({
  location: config.locationType
});

Router.map(function() {
  this.route('login');
  this.route('signup');
  this.route('user', { path: '/:name' });
});

export default Router;

Model (via Ember Data)

The model knows how to fetch and update your server data.

$ curl beenz.joshwlewis.com/users
[{"id":10,"name":"Mr. Meow","beenz":4,"gravatar_url":"..."}]
// app/models/user.js
import DS from 'ember-data';

export default DS.Model.extend({
  name: DS.attr('string'),
  beenz: DS.attr('number', { defaultValue: 3 }),
  gravatar_url: DS.attr('string'),
});

Route

Routes are responsible for loading or syncing data with the server.

// app/routes/application.js
import Ember from 'ember';

export default Ember.Route.extend({
  model() {
    return this.store.findAll('user');
  }
});

Templates

Templates automagically bind to your data

<!-- app/templates/application.hbs -->
<div class="user-list list-group">
  {{#each model as |user|}}
    {{#link-to "user" user.name class="user-list-item rainbow list-group-item"}}
      <div class="avatar">
        {{beenz-gravatar url=user.gravatar_url}}
      </div>
      <div class="info">
        <div class="name">{{user.name}}</div>
        <div class="beenz">{{beenz-kitties beenz=user.beenz}}</div>
      </div>
    {{/link-to}}
  {{/each}}
</div>

Components



<!-- from any template -->
{{ember-kitty image=3 size=40}}
// app/components/ember-kitty.js
export default Ember.Component.extend({
  tagName: "img",
  classNames: ["kitty"],
  attributeBindings: ["src", "height", "width"],
  src: Ember.computed("image", function() {
    return `/assets/images/kitty-${this.get('image')}.png`;
  }),
  height: Ember.computed.reads("size"),
  width: Ember.computed('height', function() {
    return Math.round(this.get("height") * 1.17);
  })
});

Composing components



// app/components/beenz-kitties.js
export default Ember.Component.extend({
  tagName: 'span',
  classNames: ['kitties'],

  kitties: Ember.computed('beenz', function() {
    return [1,2,3,4,5].map((been) => {
      return {
        image: been <= this.get("beenz") ? been : 0,
        been:  been
      };
    });
  })
})
<!-- app/templates/components/beenz-kitties.hbs -->
{{#each kitties as |kitty|}}
  {{beenz-kitty image=kitty.image been=kitty.been}}
{{/each}}

Component Actions

<!-- app/templates/components/give-beenz.hbs -->
{{beenz-kitties beenz=beenz action="giveBeenz"}}
{{#if isEditing}}
  <button {{action 'save'}}>Save Beenz</button>
{{else}}
  <button {{action 'edit'}}>Change Beenz</button>
{{/if}}
// app/components/give-beenz.js
export default Ember.Component.extend({
  actions: {
    edit() {
      this.set('isEditing', true);
    },
    save() {
      this.set('isEditing', false);
      this.sendAction('action', this.get('beenz'));
    },
    giveBeenz(been) {
      this.set('beenz', been);
    }
  }
});

Persisting Data

export default Ember.ObjectController.extend({
  actions: {
    giveBeenz(beenz) {
      const rating = this.get('model.rating')
      rating.set('beenz', beenz);
      rating.save().then(() => {
        this.flashMessages.success(`Gave ${beenz} beenz :)`);
      }, () => {
        this.flashMessages.warning("Error giving beenz :(");
      });
    }
  }
});

Thanks!

Resources for this talk:

Slides
joshwlewis.com/slides/emberjs
Embeenz
github.com/joshwlewis/embeenz
Ember.js
emberjs.org

Come visit us at Memphis Ruby: memphisruby.org