...for 2012
Conventions for
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;
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'),
});
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 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>
<!-- 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);
})
});
// 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}}
<!-- 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);
}
}
});
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 :(");
});
}
}
});
Resources for this talk: