This document provides an overview of managing state in a single page application with Ember.js. It discusses how Ember uses models, controllers and bindings to connect user interfaces and keep data in sync across components. Key aspects covered include Ember objects, computed properties, observers, controllers, bindings and the Ember run loop which handles updating the DOM efficiently.
2. Ember.js
• This is only to pique your interest
• Browser based MVC framework
• Builds on JQuery
• Beyond event driven abstractions
• Auto updating of DOM
5. User Template Task Template
mustache template mustache template
User View Magic! Task View
Users Controller Tasks Controller
selectedUser selectedUser
User Model Task Model
name description
tasks
prettyName
Binding
6. User Template Task Template
mustache template mustache template
Magic
User View Magic! Task View
Users Controller Tasks Controller
selectedUser selectedUser
User Model Task Model
name description
tasks
prettyName
Binding
7. Ember Models
User = Ember.Object.extend({
name: null,
tasks: []
});
/* create two users */
bob = User.create({ name: "Bob" });
mark = User.create({ name: "Mark" });
bob.get("name"); //=> "Bob"
mark.get("name"); //=> "Mark"
8. Ember Models
User = Ember.Object.extend({
name: null,
tasks: []
});
/* create two users */
bob = User.create({ name: "Bob" });
mark = User.create({ name: "Mark" });
bob.get("name"); //=> "Bob"
mark.get("name"); //=> "Mark"
9. Users Controller
// A standard Ember Object
MyApp.usersController = Ember.Object.create({
users: [],
selectedUser: null,
});
MyApp.usersController.set("users", [bob, mark]);
// fake a <click> event
MyApp.usersController.set(“selectedUser”, bob);
MyApp.usersController.getPath("selectedUser.name");
//=> "Bob"
10. Users Controller
// A standard Ember Object
MyApp.usersController = Ember.Object.create({
users: [],
selectedUser: null,
});
MyApp.usersController.set("users", [bob, mark]);
// fake a <click> event
MyApp.usersController.set(“selectedUser”, bob);
Magic
MyApp.usersController.getPath("selectedUser.name");
//=> "Bob"
11. Encapsulation
• Users View should only care about
the Users Controller
• Tasks View should only care about
the Tasks Controller
12. User Template Task Template
mustache template mustache template
User View Task View
Users Controller Tasks Controller
selectedUser selectedUser
User Model Task Model
name description
tasks
prettyName
13. Tasks Controllers
// A standard Ember Object
MyApp.tasksController = Ember.Object.create({
selectedUserBinding: 'MyApp.usersController.selectedUser'
});
MyApp.tasksController.getPath("selectedUser.name");
//=> "Mark" (or "Bob")
14. Tasks Controllers
Magic
// A standard Ember Object
MyApp.tasksController = Ember.Object.create({
selectedUserBinding: 'MyApp.usersController.selectedUser'
});
MyApp.tasksController.getPath("selectedUser.name");
//=> "Mark" (or "Bob")
15. Observers
MyApp.tasksController = Ember.Object.create({
selectedUserBinding: 'MyApp.usersController.selectedUser',
filterResults: function() {
document.write("filter the results");
// triggers a re-render
}.observes('selectedUser')
});
// somehow the selected user is changed!
MyApp.usersController.set("selectedUser", mark);
MyApp.tasksController.getPath("selectedUser.name");
//=> "Mark" (or "Bob")
// side effect of "filter the results and re-render"
16. Observers
MyApp.tasksController = Ember.Object.create({
selectedUserBinding: 'MyApp.usersController.selectedUser',
filterResults: function() {
document.write("filter the results");
// triggers a re-render
}.observes('selectedUser')
});
// somehow the selected user is changed!
MyApp.usersController.set("selectedUser", mark);
MyApp.tasksController.getPath("selectedUser.name");
//=> "Mark" (or "Bob")
// side effect of "filter the results and re-render"
17. Observers
MyApp.tasksController = Ember.Object.create({
selectedUserBinding: 'MyApp.usersController.selectedUser',
filterResults: function() {
document.write("filter the results");
// triggers a re-render
}.observes('selectedUser')
});
// somehow the selected user is changed!
MyApp.usersController.set("selectedUser", mark);
MyApp.tasksController.getPath("selectedUser.name");
//=> "Mark" (or "Bob")
// side effect of "filter the results and re-render"
24. The Run Loop
• Pops a function on the queue
• (sync, actions, destroy, timers)
• Triggered each Browser Event Loop
• JavaScript FAST - DOM slow
25. The Run Loop
Magic just
• Pops a function on the queue
• got real!
(sync, actions, destroy, timers)
• Triggered each Browser Event Loop
• JavaScript FAST - DOM slow
26. What we just saw
• Data propagated through multiple
objects
• computed properties
• observers
• bindings
• Data updated in batch
27. What do I know?
• Very steep learning curve
• (~4 weeks to get past novice)
• Modern Browsers Only
• Very, very powerful
* you are web specialists, so I&#x2019;m going to speak in code.\n* Using Ember to make Single Page WebApps like...\n* Gmail/Google Docs, iWork, Jetstar Hotels website\n\n
This talk: Seriously, I only have 5 minutes!\n* technical, pique your interest\n\n* this talk is on the Ember Data Model - moving data around\n* Give you a lightning run-through of the Ember Object Model.\n\n* no time for talk about auto updating DOM (batchy)\n
An example application\n1 - list of users - models and controllers\n2 - list of tasks - models and controllers\n3 - me! - modify a property\n\nWarning - a bit contrived. Not production quality code!\n
An example application\n1 - list of users - models and controllers\n2 - list of tasks - models and controllers\n3 - me! - modify a property\n\nWarning - a bit contrived. Not production quality code!\n
An example application\n1 - list of users - models and controllers\n2 - list of tasks - models and controllers\n3 - me! - modify a property\n\nWarning - a bit contrived. Not production quality code!\n
An example application\n1 - list of users - models and controllers\n2 - list of tasks - models and controllers\n3 - me! - modify a property\n\nWarning - a bit contrived. Not production quality code!\n
An example application\n1 - list of users - models and controllers\n2 - list of tasks - models and controllers\n3 - me! - modify a property\n\nWarning - a bit contrived. Not production quality code!\n
An example application\n1 - list of users - models and controllers\n2 - list of tasks - models and controllers\n3 - me! - modify a property\n\nWarning - a bit contrived. Not production quality code!\n
* focus on models and controllers\n* the arrows show data movement\n* create a user model and controller\n
* focus on models and controllers\n* the arrows show data movement\n* create a user model and controller\n
* focus on models and controllers\n* the arrows show data movement\n* create a user model and controller\n
Simple User Model.\nHook up to view\n
* long lived\n* created at app instantiation time\n* Somehow a user is selected\n* hook the Users Controller up to a view\n
* long lived\n* created at app instantiation time\n* Somehow a user is selected\n* hook the Users Controller up to a view\n
* long lived\n* created at app instantiation time\n* Somehow a user is selected\n* hook the Users Controller up to a view\n
\n
* the data we set in the controller (i.e. the selectedUser) is available to the view. We don&#x2019;t want the Task View to use the user controllers data.\n* need to get the selectedUser over to the TasksController to update the list of tasks\n\n
* there is now a selectedUser attribute on the controller object\n* the Tasks Controller is nicely encapsulated - doesn&#x2019;t need to reach outside itself\n* this is the magic! Declaratively wire up data\n* The Task View only needs to reference the Tasks Controller\n* data just appears\n* refs are strings (lazily evaluated)\n
* there is now a selectedUser attribute on the controller object\n* the Tasks Controller is nicely encapsulated - doesn&#x2019;t need to reach outside itself\n* this is the magic! Declaratively wire up data\n* The Task View only needs to reference the Tasks Controller\n* data just appears\n* refs are strings (lazily evaluated)\n
* observers notify you when a property changes so you can perform an action\n * kinda like an event, but not really\n
* observers notify you when a property changes so you can perform an action\n * kinda like an event, but not really\n
1 - list of users\n2 - list of tasks\n3 - me!\n
1 - list of users\n2 - list of tasks\n3 - me!\n
MyApp - Ember App Object\nprettyName - puts &#x201C;(me)&#x201D; on the current user\nAccess it as a property, not a function! It looks like data, not behaviour.\ngetPath can traverse an object graph!\nCould also have a setter computed property - full name &#x201C;John Smith&#x201D;\n
MyApp - Ember App Object\nprettyName - puts &#x201C;(me)&#x201D; on the current user\nAccess it as a property, not a function! It looks like data, not behaviour.\ngetPath can traverse an object graph!\nCould also have a setter computed property - full name &#x201C;John Smith&#x201D;\n
MyApp - Ember App Object\nprettyName - puts &#x201C;(me)&#x201D; on the current user\nAccess it as a property, not a function! It looks like data, not behaviour.\ngetPath can traverse an object graph!\nCould also have a setter computed property - full name &#x201C;John Smith&#x201D;\n
MyApp - Ember App Object\nprettyName - puts &#x201C;(me)&#x201D; on the current user\nAccess it as a property, not a function! It looks like data, not behaviour.\ngetPath can traverse an object graph!\nCould also have a setter computed property - full name &#x201C;John Smith&#x201D;\n
MyApp - Ember App Object\nprettyName - puts &#x201C;(me)&#x201D; on the current user\nAccess it as a property, not a function! It looks like data, not behaviour.\ngetPath can traverse an object graph!\nCould also have a setter computed property - full name &#x201C;John Smith&#x201D;\n
MyApp - Ember App Object\nprettyName - puts &#x201C;(me)&#x201D; on the current user\nAccess it as a property, not a function! It looks like data, not behaviour.\ngetPath can traverse an object graph!\nCould also have a setter computed property - full name &#x201C;John Smith&#x201D;\n
* OMG - super fast. Too fast for some of our users!\n* Computed Properties, Observers, Bindings are all managed within a run loop\n* Each set call is put on a queue (as a function) and popped off at the end of the run loop.\n* 4 queues - sync (bindings), actions (once off), destroy (remove objects), timers\n * we&#x2019;ve seen 1000&#x2019;s of items in the queues (normally 100s)\n* JavaScript is FAST - DOM is slow\n* getters, setters and creates are very powerful\n\n
* OMG - super fast. Too fast for some of our users!\n* Computed Properties, Observers, Bindings are all managed within a run loop\n* Each set call is put on a queue (as a function) and popped off at the end of the run loop.\n* 4 queues - sync (bindings), actions (once off), destroy (remove objects), timers\n * we&#x2019;ve seen 1000&#x2019;s of items in the queues (normally 100s)\n* JavaScript is FAST - DOM is slow\n* getters, setters and creates are very powerful\n\n
\n
* Only for Modern Browsers - IE6 and 7 have slow JS runtimes - Chrome Frame\n* It blows your mind until you have an example to grasp onto. Doc isn&#x2019;t great.\n* don&#x2019;t try to combine this with CoffeeScript & Jasmine at first - too much learning\n* very terse, modular code\n\n
* please follow me on Twitter @markmansour @agilebench\n* 20 years on the intertubes. Pre-web baby! nntp and gopher FTW!\n