Managing State in Single Page WebApps with Ember.js
Upcoming SlideShare
Loading in...5
×
 

Managing State in Single Page WebApps with Ember.js

on

  • 8,121 views

A whirlwind tour of Ember.js' Data Model and how data is propagated to objects.

A whirlwind tour of Ember.js' Data Model and how data is propagated to objects.

Presented at What Do You Know Melbourne.

Statistics

Views

Total Views
8,121
Views on SlideShare
8,065
Embed Views
56

Actions

Likes
7
Downloads
138
Comments
2

2 Embeds 56

http://www.xeqtit.com 51
http://www.linkedin.com 5

Accessibility

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • * you are web specialists, so I’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’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’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’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 “(me)” 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 “John Smith”\n
  • MyApp - Ember App Object\nprettyName - puts “(me)” 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 “John Smith”\n
  • MyApp - Ember App Object\nprettyName - puts “(me)” 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 “John Smith”\n
  • MyApp - Ember App Object\nprettyName - puts “(me)” 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 “John Smith”\n
  • MyApp - Ember App Object\nprettyName - puts “(me)” 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 “John Smith”\n
  • MyApp - Ember App Object\nprettyName - puts “(me)” 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 “John Smith”\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’ve seen 1000’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’ve seen 1000’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’t great.\n* don’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

Managing State in Single Page WebApps with Ember.js Managing State in Single Page WebApps with Ember.js Presentation Transcript

  • Managing State in Single Page with Ember.js 16 Feb
  • Ember.js• This is only to pique your interest• Browser based MVC framework• Builds on JQuery• Beyond event driven abstractions• Auto updating of DOM
  • Models Controllers
  • Models Controllers
  • User Template Task Templatemustache template mustache template User View Magic! Task View Users Controller Tasks ControllerselectedUser selectedUser User Model Task Modelname descriptiontasksprettyName Binding
  • User Template Task Templatemustache template mustache template Magic User View Magic! Task View Users Controller Tasks ControllerselectedUser selectedUser User Model Task Modelname descriptiontasksprettyName Binding
  • Ember ModelsUser = 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"
  • Ember ModelsUser = 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"
  • Users Controller// A standard Ember ObjectMyApp.usersController = Ember.Object.create({ users: [], selectedUser: null,});MyApp.usersController.set("users", [bob, mark]);// fake a <click> eventMyApp.usersController.set(“selectedUser”, bob);MyApp.usersController.getPath("selectedUser.name");//=> "Bob"
  • Users Controller// A standard Ember ObjectMyApp.usersController = Ember.Object.create({ users: [], selectedUser: null,});MyApp.usersController.set("users", [bob, mark]);// fake a <click> eventMyApp.usersController.set(“selectedUser”, bob); MagicMyApp.usersController.getPath("selectedUser.name");//=> "Bob"
  • Encapsulation• Users View should only care about the Users Controller• Tasks View should only care about the Tasks Controller
  • User Template Task Templatemustache template mustache template User View Task View Users Controller Tasks ControllerselectedUser selectedUser User Model Task Modelname descriptiontasksprettyName
  • Tasks Controllers // A standard Ember ObjectMyApp.tasksController = Ember.Object.create({ selectedUserBinding: MyApp.usersController.selectedUser});MyApp.tasksController.getPath("selectedUser.name");//=> "Mark" (or "Bob")
  • Tasks Controllers Magic // A standard Ember ObjectMyApp.tasksController = Ember.Object.create({ selectedUserBinding: MyApp.usersController.selectedUser});MyApp.tasksController.getPath("selectedUser.name");//=> "Mark" (or "Bob")
  • ObserversMyApp.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"
  • ObserversMyApp.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"
  • ObserversMyApp.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"
  • Computed PropsUser = Ember.Object.extend({    name: null, currentUserBinding: ‘MyApp.currentUser’, // computed property prettyName: function() { if(this == this.get(“currentUser”)) return this.get(“name”) + " (me)"; return this.get(“name”); }.property("name")});bob.get("prettyName"); //=> "Bob"mark.get("prettyName"); //=> "Mark (me)"
  • Computed PropsUser = Ember.Object.extend({    name: null, currentUserBinding: ‘MyApp.currentUser’, // computed property prettyName: function() { if(this == this.get(“currentUser”)) return this.get(“name”) + " (me)"; return this.get(“name”); }.property("name")});bob.get("prettyName"); //=> "Bob"mark.get("prettyName"); //=> "Mark (me)"
  • Computed PropsUser = Ember.Object.extend({    name: null, currentUserBinding: ‘MyApp.currentUser’, // computed property prettyName: function() { if(this == this.get(“currentUser”)) return this.get(“name”) + " (me)"; return this.get(“name”); }.property("name")});bob.get("prettyName"); //=> "Bob"mark.get("prettyName"); //=> "Mark (me)"
  • Computed PropsUser = Ember.Object.extend({    name: null, currentUserBinding: ‘MyApp.currentUser’, // computed property prettyName: function() { if(this == this.get(“currentUser”)) return this.get(“name”) + " (me)"; return this.get(“name”); }.property("name")});bob.get("prettyName"); //=> "Bob" MOAR Magicmark.get("prettyName"); //=> "Mark (me)"
  • The Run Loop• Pops a function on the queue • (sync, actions, destroy, timers)• Triggered each Browser Event Loop• JavaScript FAST - DOM slow
  • 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
  • What we just saw• Data propagated through multiple objects • computed properties • observers • bindings• Data updated in batch
  • What do I know?• Very steep learning curve • (~4 weeks to get past novice)• Modern Browsers Only• Very, very powerful
  • Agile BenchPlanning tool for agile teams