ember background basics
DESCRIPTION
http://github.com/sideshowcoder/javascript-workshopTRANSCRIPT
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 Observerfunction 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-run-loop-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 !