Basics for Ember.js
An introduction and some history
Stuck? Here are some resources…
•

https://developer.mozilla.org/en-US/

•

http://underscorejs.org

•

http://pivotal.github.io/jasmine/

•

http://www.2ality.com/2013/06/basic-javascript.html

•

http://www.2ality.com/2013/07/meta-style-guide.html
Getting better…
•

http://exercism.io/

•

Read Code:
•

https://github.com/jashkenas/underscore/blob/master/
underscore.js

•

https://github.com/jashkenas/backbone/blob/master/
backbone.js

•

https://github.com/emberjs/ember.js/tree/master/
packages
Some small things first
function.bind
function foo(bar) {
console.log(bar)
return bar
}
!

var f = foo.bind(null, "hello world")
console.log(typeof f) // function
f() // outputs hello world
Passing functions around
function Ork() {
this.description = "I am an Ork"
}
!

Ork.prototype.describe = function() {
console.log(this.description)
}
!

var ork = new Ork()
ork.describe() // I am an Ork
!

setTimeout(ork.describe, 100) // undefined
setTimeout(ork.describe.bind(ork), 100) // I am an Ork
MVC != MVC
Server-side MVC is not the only way!
Rails MVC
Observers
Embers MVC relies on Observers
Observers are a central part to MVC here
So what is the observer pattern?
http://addyosmani.com/resources/essentialjsdesignpatterns/
book/
“The observer pattern is a software design pattern in
which an object, called the subject, maintains a list of
its dependents, called observers, and notifies them
automatically of any state changes, usually by calling
one of their methods.” — Wikipedia
Observable
functions Ork(name) {
this.name = name
this._observers = []
}
!

Ork.prototype.smash = function(thing) {
this._observers.forEach(function(o) {
o.notify(this, "smashed " + thing);
}, this)
}
!

Ork.prototype.registerObserver = function(observer) {
this._observers.push(observer)
}
Observer
function OrkMaster(name) {
this.name = name
}
!

OrkMaster.prototype.notify = function(ork, message) {
console.log(this.name + " here " +
ork.name + " told me he "
+ message)
}
!

OrkMaster.prototype.observe = function(ork) {
ork.registerObserver(this)
}
Putting it all together

var master = new OrkMaster("Uruk-hai")
var gobgrub = new Ork("Gobgrub")
var nazsnaga = new Ork("Nazsnaga")
!

master.observe(gobgrub)
master.observe(nazsnaga)
!

gobgrub.smash("human")
nazsnaga.smash("drawf")
!

// Uruk-hai here Gobgrub told me he smashed human
// Uruk-hai here Nazsnaga told me he smashed drawf
http://jsfiddle.net/sideshowcoder/fRDDL/
JavaScript already offers this via events
Evented Observerable

function Ork(name) {
this.name = name
var _e = document.createElement("div")
this.dispatchEvent = _e.dispatchEvent.bind(_e)
this.addEventListener = _e.addEventListener.bind(_e)
}
!

Ork.prototype.smash = function(thing) {
var evData = { message: "smashed " + thing, ork: this }
var ev = new CustomEvent("orkevent", { detail: evData })
this.dispatchEvent(ev)
}
Evented Observer
function OrkMaster(name) {
this.name = name
}
!

OrkMaster.prototype.handleEvent = function(ev) {
var ork = ev.detail.ork
var message = ev.detail.message
console.log(this.name + " here " +
ork.name + " told me he "
+ message)
}
!

OrkMaster.prototype.observe = function(ork) {
var handler = this.handleEvent.bind(this)
ork.addEventListener("orkevent", handler)
}
http://jsfiddle.net/sideshowcoder/5cPAg/
Why do all this?
Decoupling
Automatic updates, or Data Binding
!

!

!

!
!
!

function Ork() {
this._observers = []
}
Ork.prototype.setName = function(name) {
this.name = name
this._observers.forEach(function(o) {
o.notify(this)
}, this)
}
Ork.prototype.addObserver = function(observer) {
this._observers.push(observer)
}
var nameObserver = {
notify: function(ork) {
document.getElementById("ork-name").innerHTML = ork.name
}
}
var ork = new Ork()
ork.addObserver(nameObserver)
ork.setName("Bar")
setTimeout(function() {
ork.setName("Gobgrub")
}, 1000)
http://jsfiddle.net/sideshowcoder/GLfbn/
http://jsfiddle.net/sideshowcoder/J2Cn6/
Only the model is the source for data
There is not “It’s over after the request is done”
The Run Loop
Ember.run
“…is a programming construct that waits for and
dispatches events or messages in a program”
!

Thanks Wikipedia!
https://machty.s3.amazonaws.com/ember-runloop-visual/index.html
Why in Ember?
Ember needs some boundaries!
Model layer is “THE TRUTH”™
Performance
MVCs all the way down
The Routes / Router are the “Grand Daddy”
Ember did not invent this
Ember ~ Sproutcore ~ Cocoa
If you want to understand Ember look at Cocoa
!
And listen to Yehuda Katz…
!
http://www.youtube.com/watch?v=s1dhXamEAKQ
!

Ember background basics