Emberjs is an opinionated web UI framework focused on developer productivity. I will introduce the basics of the framework, and provide several examples of where ember saves an unprecedented amount of time for dev teams. Additionally, I'll cover ember-cli, the extensible build tool that the Emberjs and Angular communities are depending on for code generation, asset compilation, and running tests
7. NOW IMAGINE…
• All the micro-libraries
• All the build tools
• All the pre-processors and post-processors
• All of the permutations with typescript, babel, etc…
16. THE EMBER ECOSYSTEM
ember-cli
Code Generation
Asset Pipeline
Plugins
Extensible CLI
Test Runner
ember.js
SPA routing
Components
Templating
Data Binding
Prioritized Work Queue
ember-data
Request Construction
JSON Serialization
Redux-like Data Flow
Async Relationships
liquid-fire
animations
ember-collection
virtualized list
17. THE EMBER ECOSYSTEM
• Built on strong conventions & opinions
• Focus on developer productivity
• Aligned with web standards
• Abstractions hold up w/ large scale & complexity
• Constantly improving
18. TEMPLATING
• Handlebars
• Declarative markup, an extension of
HTML
• Compiled at build time
• Extensible
Hello,
<strong>
{{firstName}} {{lastName}}
</strong>!
19. define('examples/templates/index', ['exports'], function (exports) {
'use strict';
exports['default'] = Ember.HTMLBars.template((function() {
return {
...
buildFragment: function buildFragment(dom) {
var el0 = dom.createDocumentFragment();
var el1 = dom.createTextNode("Hello, ");
dom.appendChild(el0, el1);
var el1 = dom.createElement("strong");
var el2 = dom.createComment("");
dom.appendChild(el1, el2);
var el2 = dom.createTextNode(" ");
dom.appendChild(el1, el2);
var el2 = dom.createComment("");
dom.appendChild(el1, el2);
dom.appendChild(el0, el1);
var el1 = dom.createTextNode("!");
dom.appendChild(el0, el1);
return el0;
},
buildRenderNodes: function buildRenderNodes(dom, fragment,
contextualElement) {
var element0 = dom.childAt(fragment, [1]);
var morphs = new Array(2);
morphs[0] = dom.createMorphAt(element0,0,0);
morphs[1] = dom.createMorphAt(element0,2,2);
return morphs;
},
statements: [
["content","firstName",["loc",[null,[1,15],[1,28]]]],
["content","lastName",["loc",[null,[1,29],[1,41]]]]
],
...
};
}()));
});
20. TEMPLATING
• Helpers
• Block vs inline form
• Easy to read and reason about
My pet goes
{{#if isDog}}
arf
{{else}}
meow
{{/if}}
My pet goes {{if isDog "arf"
"meow"}}
21. My pet goes {{if isDog "arf" "meow"}}
function ifHelper(condition, ifTrue, ifFalse) {
return condition ? ifTrue : ifFalse
}
{{#if isEnabled}}
<b>Switch is enabled</b>
{{/if}}
function ifHelper(condition, callbackIfTrue) {
return condition ? callbackIfTrue() : '';
}
22. <ul>
{{#each arr as |item|}}
<li>{{item.name}}</li>
{{/each}}
</ul>
function eachHelper(array, cb) {
return array
.map(item => cb(item))
.join('');
}
23. ROUTING
• Router - Finite State Machine
• Routes - Manage transitions between
states
• URLs drive your app this is a core pillar
of Ember
36. <my-widget title='Enter your Info'>
<my-field name='Username'/>
<my-field name='Password'/>
</my-widget>
{{#my-widget title='Enter your Info’}}
{{my-field name=‘Username’}}
{{my-field name=‘Password’}}
{{/my-widget}}
37. init on instantiation
willInsertElement before the component’s element is inserted into the DOM
didInsertElement after the component’s element has been inserted into the DOM
willDestroyElement before the component’s element is removed from the DOM
$(document).ready() for components
Clean up before tear down
EMBER.COMPONENT
38. EMBER-DATA
• Unidirectional data flow, single atom of state
• Can talk to any API
• Moves data massaging out of your business logic
• Built around fetch (important for SS rendering!)
• Saves tons of time if your API uses consistent conventions
39. EMBER-DATA: MODEL
• Representation of any (usually
persistent) data
• Defined by attributes, and
relationships to other models
• “model” is the factory that defines
the structure of “records”
// app/models/book.js
import DS from 'ember-data';
const { attr, hasMany } = DS;
export default DS.Model.extend({
title: attr('string'),
publishedAt: attr('date'),
chapters: hasMany('chapter')
});
40. EMBER-DATA: STORE
• Where you get/create/destroy records
• A single source of truth
• This means that all changes are kept in sync!
• Similar concept in Facebook/flux, angular-data
41. EMBER-DATA: STORE
// (maybe) API request for all records of type "author"
this.store.findAll('author');
// (maybe) API request for record of type "post" with id 37
this.store.findRecord('post', 37);
// API request for all records of type "author"
this.store.fetchAll('author');
// API request for record of type "post" with id 37
this.store.fetchRecord('post', 37);
// look in cache for all records of type "author"
this.store.peekAll('author');
// look in cache for record of type "post" with id 37
this.store.peekRecord('post', 37);