SlideShare a Scribd company logo
Backbone.js
How to write a well structured multi page
web application
Thursday, September 12, 13
About
• Ynon Perek
• ynon@ynonperek.com
• Find and download slides from:
http://ynonperek.com
Thursday, September 12, 13
Unstructured JS
• Developer Starts
writing JS code
• App gets big,
developer gets
angry
Thursday, September 12, 13
What We Want
• Build apps like lego
• Everything has a
place
Thursday, September 12, 13
JS Solution
• Separate Logic from View
• Use a framework
Thursday, September 12, 13
MV* Frameworks
Model
View
*
Thursday, September 12, 13
Available JS MV*
• And a lot more...
• Nice comparison: http://todomvc.com/
Thursday, September 12, 13
Backbone.js
• Created by Jeremy
Ashkenas
• Goal: Keep your
code AWAY from
the DOM
Thursday, September 12, 13
Reasons Why
• Well tested and proven
• Strong community
• Simple: Almost no magic
Thursday, September 12, 13
Who’s Using Backbone ?
Big list: http://backbonejs.org
Thursday, September 12, 13
Backbone (MV*)
Concepts
Thursday, September 12, 13
Application Structure
• Each “page” is just a
div
• “Page” can be a full
page or partial
<body>
  <div class="page">
    <h1>About Page</h1>
  </div>
  <div class="page">
    <h1>Main Page</h1>
  </div>
  <div class="page">
    <h1>Item Info</h1>
  </div>
 
</body>
Thursday, September 12, 13
Application Structure
• Navigating in the app is just calling a
route function
• Route function slides divs in-and-out
help: function() {
  alert('What can I help you with ?');
}
Thursday, September 12, 13
Application Structure
• Implementing Client-side logic
• Models “know”
• Views “show”
Thursday, September 12, 13
Application Structure
Model View DOM
Store Data Renders Data
Thursday, September 12, 13
Models
• Models store your data
• Models have no visual representation
• Functionality for managing changes
Thursday, September 12, 13
Views
• A View provides the visual representation
of a model
Task Model
Thursday, September 12, 13
Collections
• Models are usually grouped in collections
* Task Model
* Task Model
* Task Model
Daily
Tasks
Walk the dog
Water the plans
Thursday, September 12, 13
Backbone Benefits
• Good separation of
concerns
• Best for large client-
side applications
Thursday, September 12, 13
What Backbone Is Not
• It’s not a framework
• So it’s ok to use only parts of it
Thursday, September 12, 13
What Backbone Is Not
• It’s not for small apps that just
“show data”
• Backbone assumes client-side logic
Thursday, September 12, 13
What Backbone Is Not
• It will never get in your way :)
Thursday, September 12, 13
Coding Time
Thursday, September 12, 13
Todo App
• Model for each task
• View for each task
• Main application view
Thursday, September 12, 13
Task Model
(function(global) {
 
    global.models.Task = Backbone.Model.extend({
        defaults: {
            completed: false,
            text: ''
        }
    });
 
}(this));
Thursday, September 12, 13
Task Model
(function(global) {
 
    global.models.Task = Backbone.Model.extend({
        defaults: {
            completed: false,
            text: ''
        }
    });
 
}(this));
Define a new model
Thursday, September 12, 13
Task Model
(function(global) {
 
    global.models.Task = Backbone.Model.extend({
        defaults: {
            completed: false,
            text: ''
        }
    });
 
}(this));
Set default values
Thursday, September 12, 13
Task View
    global.views.TaskView = Backbone.View.extend({
        tagName: "div",
        className: "task",
        events: {
            "click" : "handle_click"
        },
Define a new View
Thursday, September 12, 13
Task View
    global.views.TaskView = Backbone.View.extend({
        tagName: "div",
        className: "task",
        events: {
            "click" : "handle_click"
        },
Specify HTML element
Thursday, September 12, 13
Task View
    global.views.TaskView = Backbone.View.extend({
        tagName: "div",
        className: "task",
        events: {
            "click" : "handle_click"
        },
Define Event Handlers
name of a method that will be
called when the view is clicked
Thursday, September 12, 13
View Rendering
• render() method of a view is used to
render it to HTML
• Usually implemented with client side
template engine
Thursday, September 12, 13
Task View
        render: function() {
            this.$el.html( this.template( this.model.toJSON()));
            return this;
        },
        template: Handlebars.compile($('#task-template').html())
Define Render Function
Thursday, September 12, 13
Task View
        render: function() {
            this.$el.html( this.template( this.model.toJSON()));
            return this;
        },
        template: Handlebars.compile($('#task-template').html())
Paint The View onto HTML
Thursday, September 12, 13
Task View
        render: function() {
            this.$el.html( this.template( this.model.toJSON()));
            return this;
        },
        template: Handlebars.compile($('#task-template').html())
Handlebars is used as a template engine
Thursday, September 12, 13
Task View
        initialize: function(opts) {
            this.model.on('change', this.render, this );
        },
        handle_click: function() {
            if ( this.model.get('completed') ) {
                this.model.set('completed', false);
            } else {
                this.model.set('completed', true);
            }
        },
initialize is called from a view’s constructor
Thursday, September 12, 13
Task View
        initialize: function(opts) {
            this.model.on('change', this.render, this );
        },
        handle_click: function() {
            if ( this.model.get('completed') ) {
                this.model.set('completed', false);
            } else {
                this.model.set('completed', true);
            }
        },
We use it to bind event handlers on the model
Thursday, September 12, 13
Task View
        initialize: function(opts) {
            this.model.on('change', this.render, this );
        },
        handle_click: function() {
            if ( this.model.get('completed') ) {
                this.model.set('completed', false);
            } else {
                this.model.set('completed', true);
            }
        },
Implementing the clicks handler
Thursday, September 12, 13
Main App View
    global.views.AppView = Backbone.View.extend({
        el: $('body'),
        events: {
            "click .add-btn": "add_task"
        },
        add_task: function() {
            var task_description = this.$el.find('input').val();
            var tm = new global.models.Task({ text: task_description });
            var tv = new global.views.TaskView({model: tm});
            this.$el.find('ul').append(tv.render().el);
            this.$el.find('input').val('');
        }
    });
Thursday, September 12, 13
Take Aways
• Models keep data
• Views show data
• Views listen for model changes using on
• Views listen for DOM changes using
events
Thursday, September 12, 13
Lab
• Add a “Priority” field to a task
• Render high priority tasks in red, medium
priority tasks in yellow and normal in
green
Thursday, September 12, 13
Backbone Router
• A Router connects URL with application
state
• This allows internal bookmarking and
history management
Thursday, September 12, 13
Hello Router
• You only
need
one
• Defines
routes
and
handlers
var router = new (Backbone.Router.extend({
  routes: {
    '' : 'home',
    'help' : 'help'
  },
 
  home: function() {
    alert('WElcome home');
  },
 
  help: function() {
    alert('What can I help you with ?');
  }
}))();
 
Backbone.history.start({ pushState: true } );
Thursday, September 12, 13
Changing State
• Use router.navigate( url ) to
change state
• Pass { trigger: true } if you need to
also trigger the route
Thursday, September 12, 13
Demo
• Let’s add a View Task page
• Shows a specific task in details
• Then connect the pages using a router
Thursday, September 12, 13
Server Side
Models
How to get server data using
Backbone Models
Thursday, September 12, 13
Models & The Server
• Set the urlRoot property of a model to
allow it to sync with your server
Thursday, September 12, 13
Models & The Server
Model Id
Model
Method
HTTP Method Url
id == 1 .fetch() GET /todos/1
id == 1 .save() PUT /todos/1
no id .fetch() GET /todos
no id .save() POST /todos
Thursday, September 12, 13
Server Events
• request event is triggered when sync
starts
• change event is triggered when an
attribute value has changed
• sync event is triggered when save is
completed (i.e. data is saved on server)
Thursday, September 12, 13
Server URLs
• POST /items => return a new item
• GET /items/id => return an existing
item by its id
• PUT /items/id => change existing
item by its id
Thursday, September 12, 13
Demo:
https://github.com/ynonp/mobileweb-
examples/tree/master/ajax/Backbone
Thursday, September 12, 13
Q & A
Thursday, September 12, 13
Collections
Thursday, September 12, 13
Collections
• Groups of models
• Add/Remove events
• Sync from server
Thursday, September 12, 13
Collections
Feed The Zombie
Plant The Brainz
Do The Zombie Walk
Todos Collection
Todo Models
Thursday, September 12, 13
Collection Actions
• col.length : number of models in
the collection
• col.add(m) : add a model
• col.remove(m) : remove a model
Thursday, September 12, 13
Collection Actions
• col.at( index ) : get a model at a
specific index
• col.get( id ) : get a model by its id
Thursday, September 12, 13
Collection Actions
• reset( array_of_models ) : sets the
collection’s data
Thursday, September 12, 13
Collections Demo
• Add a Tasks collection
• Add a Counter view
• Show active tasks count
Thursday, September 12, 13
Collections
    global.models.TasksGroup = Backbone.Collection.extend({
        model: global.models.Task
    })
Define a new collection
A collection needs to create objects, so we must
provide the type as a class
Thursday, September 12, 13
Collection Views
• It’s ok to create a view for a collection
• Just pass in the collection to the view’s
new method
• Render delegates its job to subviews
• Demo: Create a collection view for
TasksGroup
Thursday, September 12, 13
Collection Views
render: function() {
  var $el = this.$el;
 
  $el.html('');
 
  this.collection.forEach(function(model) {
    var v = new app.views.Task( { model: model } );
    $el.append( v.render() );
  });
 
  return $el;
},
Thursday, September 12, 13
Collection Views
render: function() {
  var $el = this.$el;
 
  $el.html('');
 
  this.collection.forEach(function(model) {
    var v = new app.views.Task( { model: model } );
    $el.append( v.render() );
  });
 
  return $el;
},
Pop Quiz:
What can go wrong ?
Thursday, September 12, 13
Managing Subviews
• If subviews also listen for model events,
you will need to stop listening before
removing the container view
• Solution: keep a list of subviews in
container
Thursday, September 12, 13
More Collection Views
• Same data, different views
• Let’s create a counter view
• Show total number of tasks
Thursday, September 12, 13
Collections
       initialize: function() {
            var cv = new global.views.CounterView(
{ tasks: this.tasks }).render();
            this.$el.append( cv.el );
            this.tasks.on('add', cv.render, cv );
            this.tasks.on('remove', cv.render, cv);
        },
In appview.js
Collections trigger events when models are
added or removed
Thursday, September 12, 13
Collections
   global.views.CounterView = Backbone.View.extend({
        tagName: 'div',
        className: 'counter',
        initialize: function(opts) {
            this.tasks = opts.tasks;
        },
        render: function() {
            console.dir(this.el);
            this.$el.html( this.template(
{ count: this.tasks.length }));
            return this;
        },
        template: Handlebars.compile( $('#counter-template').html() )
    });
Thursday, September 12, 13
Lab
• Modify CounterView so it will also display
the number of unfinished tasks
Thursday, September 12, 13
Other Collection Methods
• forEach (function(item) { ... } )
• find
• filter
• include
• toArray
Thursday, September 12, 13
Collection and Server
• Retrieve a collection from the server
using fetch()
• url is a property of collection
• change event is triggered if server state is
different
Thursday, September 12, 13
Collections Server URLs
• GET /items => returns all items
Thursday, September 12, 13
Collection Events
• reset event is triggered after fetch() or
reset()
• add() event is triggered when a model
is added to a collection
• remove() event is triggered when a
model is removed from a collection
Thursday, September 12, 13
Q & A
Thursday, September 12, 13
Extending Backbone
• Nested Collections
• Pagination
• Data Binding
• Forms
Thursday, September 12, 13
Extending Backbone
• Backbone is easy to extend:
• You can add functions to the
Backbone namespace
• You can override Backbone’s methods
Thursday, September 12, 13
Try This
• Add function toggle() to Backbone.Model
to toggle bool values (true / false)
Thursday, September 12, 13
Try This
• Create a TemplateView that acts like a
Backbone.View with a simple template
rendering functionality built-in
Thursday, September 12, 13
Backbone Extensions
• JS Libs that extend Backbone
• Really long list at:
https://github.com/jashkenas/backbone/
wiki/Extensions,-Plugins,-Resources
Thursday, September 12, 13
Nested Collections
• A collection that
“has” another
collection
• Example: Inbox and
Messages
Thursday, September 12, 13
Nested Approach
Inbox
Sent
Drafts
Models
Mail Collection
Thursday, September 12, 13
Nested Approach
Inbox
Sent
Drafts
Models
msg1
msg2
msg3
Models
Thursday, September 12, 13
Let’s Code This
• Models:
• Mailbox model
• Message model
• Collections:
• Mailbox collection (for messages)
• Folders collection (for mailboxes)
Thursday, September 12, 13
This works. But...
• Given a message item, can you tell in
which mailbox it is ?
• How do you move a message from one
inbox to another ?
Thursday, September 12, 13
Backbone-Relational
• A plugin for managing relations between
collections
• Adds RelationalModel
• http://backbonerelational.org/
Thursday, September 12, 13
Q & A
Thursday, September 12, 13
Pagination
• How would you implement pagination ?
Thursday, September 12, 13
Pagination
• Collection only stores partial data
• Add methods to collection:
• goToNextPage()
• goToPreviousPage()
• goToPage()
Thursday, September 12, 13
Pagination
• Need to override Backbone.sync to allow
sending custom parameters to the server
Thursday, September 12, 13
Backbone.Sync
• sync(method, model, [options])
• method: create / read / update / delete
• model: model or collection
• options: success and error callbacks
Thursday, September 12, 13
Backbone.Sync options
• Use a global Backbone.sync to enable
application wide overriding
• Use a model/collection specific sync to
have only that collection use your sync
Thursday, September 12, 13
Backbone.Sync Demo
• Let’s write a cacheable model that adds
two methods:
• cache()
• invalidate()
• After cache(), all read requests should
return the cached copy
Thursday, September 12, 13
Lab: Fill in the missing parts
Backbone.CachedModel = Backbone.Model.extend({
  cache: function() {
  },
 
  invalidate: function() {
  },
 
  sync: function(method, model, opts) {
  }
});
Thursday, September 12, 13
Take Aways
• Backbone.sync allows full control on the
syncing process
• If you just need to add functionality,
consider listening for sync events
Thursday, September 12, 13
Pagination
• Use a custom (paginated) collection
• Add a sync method so it’ll send your
pagination params to the server
• AND Someone already did it :)
Thursday, September 12, 13
The Backbone Way
• A special collection is added using the
Paginator plugin
• Backbone.Paginator.requestPager
Thursday, September 12, 13
Other Params
• Paginated Collection needs:
• paginator_core: an object describing
how to interact with the server
• paginator_ui: an object describing
how to display the info
• server_api: an object describing the
parameters to send
• Code: https://github.com/backbone-
paginator/backbone.paginator
Thursday, September 12, 13
Demo
• https://github.com/backbone-paginator/
backbone.paginator/tree/master/
examples/request-paging
Thursday, September 12, 13
Q & A
Thursday, September 12, 13
Other Plugins
• Backbone.localStorage will let you store
your models locally
https://github.com/jeromegn/
Backbone.localStorage
Thursday, September 12, 13
Other Plugins
• Backbone Forms will automatically
create form controls for you
• Also adds validation code
• https://github.com/powmedia/
backbone-forms
Thursday, September 12, 13
Other Plugins
• Backbone Stickit will let you have two-
ways data binding for your views
• http://nytimes.github.io/backbone.stickit/
Thursday, September 12, 13
Extending Backbone
• Extending Backbone is easy
• Just create more models, views or
controllers
• Sometimes you’ll need to override
Backbone methods
Thursday, September 12, 13
Benefits
• Lifts big apps
• Scalable and very
stable
• No magic
• Extensible
Thursday, September 12, 13
Dark Side
• Not suitable for
small apps
• Can be confusing
for new developers
• Can sometimes add
clutter
Thursday, September 12, 13
Thank You
• Ynon Perek
• me@ynonperek.com
• ynonperek.com
Thursday, September 12, 13

More Related Content

PDF
08 ajax
PDF
Scalable JavaScript
PDF
Frontend Engineer Toolbox
PDF
Writing Reusable Web Components with jQuery and jQuery UI
PPT
jQuery and_drupal
PDF
Create responsive websites with Django, REST and AngularJS
PPT
Writing Pluggable Software
PDF
[Bristol WordPress] Supercharging WordPress Development
08 ajax
Scalable JavaScript
Frontend Engineer Toolbox
Writing Reusable Web Components with jQuery and jQuery UI
jQuery and_drupal
Create responsive websites with Django, REST and AngularJS
Writing Pluggable Software
[Bristol WordPress] Supercharging WordPress Development

What's hot (20)

PDF
jQuery in 15 minutes
PPTX
Getting the Most Out of jQuery Widgets
PDF
Hybrid Web Applications
PPT
jQuery introduction
PPTX
jQuery Presentation
PDF
Django a whirlwind tour
PDF
jQuery Loves Developers - Oredev 2009
PDF
The Best (and Worst) of Django
PDF
jQuery in the [Aol.] Enterprise
PPT
High Performance Ajax Applications
PDF
The DOM is a Mess @ Yahoo
KEY
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
KEY
Geotalk presentation
PDF
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
PDF
jQuery Essentials
PDF
High Performance Ajax Applications
PDF
Everything is Awesome - Cutting the Corners off the Web
PDF
HTML5: where flash isn't needed anymore
PPTX
Introduction to jQuery
PPT
WordPress and Ajax
jQuery in 15 minutes
Getting the Most Out of jQuery Widgets
Hybrid Web Applications
jQuery introduction
jQuery Presentation
Django a whirlwind tour
jQuery Loves Developers - Oredev 2009
The Best (and Worst) of Django
jQuery in the [Aol.] Enterprise
High Performance Ajax Applications
The DOM is a Mess @ Yahoo
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Geotalk presentation
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
jQuery Essentials
High Performance Ajax Applications
Everything is Awesome - Cutting the Corners off the Web
HTML5: where flash isn't needed anymore
Introduction to jQuery
WordPress and Ajax
Ad

Similar to Backbone (20)

PDF
Ruby meetup 7_years_in_testing
PDF
Dependency Injection @ AngularJS
PDF
Building a Startup Stack with AngularJS
PDF
Intro to Ember.js
PDF
Choosing a Javascript Framework
PDF
JavaScript DOM Manipulations
PDF
Ember and containers
PDF
Tek 2013 - Building Web Apps from a New Angle with AngularJS
PDF
MongoTalk/Voyage
PDF
jQuery Mobile Deep Dive
PDF
An introduction to Ember.js
PDF
RailsAdmin - Overview and Best practices
PDF
Intro tobackbone
PDF
Angular 2 introduction
PDF
Integrate Spring MVC with RequireJS & Backbone.js & Spring Data JPA
PDF
Bundling Client Side Assets
PDF
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
PDF
Pragmatic JavaScript
PDF
Angular from Scratch
PPT
JBUG 11 - Django-The Web Framework For Perfectionists With Deadlines
Ruby meetup 7_years_in_testing
Dependency Injection @ AngularJS
Building a Startup Stack with AngularJS
Intro to Ember.js
Choosing a Javascript Framework
JavaScript DOM Manipulations
Ember and containers
Tek 2013 - Building Web Apps from a New Angle with AngularJS
MongoTalk/Voyage
jQuery Mobile Deep Dive
An introduction to Ember.js
RailsAdmin - Overview and Best practices
Intro tobackbone
Angular 2 introduction
Integrate Spring MVC with RequireJS & Backbone.js & Spring Data JPA
Bundling Client Side Assets
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
Pragmatic JavaScript
Angular from Scratch
JBUG 11 - Django-The Web Framework For Perfectionists With Deadlines
Ad

More from Ynon Perek (20)

PDF
Regexp
PDF
Html5 intro
PDF
09 performance
PDF
Mobile Web Intro
PDF
Qt multi threads
PDF
Vimperl
PDF
Syllabus
PDF
Mobile Devices
PDF
Network
PDF
Architecture app
PDF
Cryptography
PDF
Unit Testing JavaScript Applications
PDF
How to write easy-to-test JavaScript
PDF
Introduction to Selenium and Ruby
PDF
Introduction To Web Application Testing
PDF
Accessibility
PDF
Angularjs
PDF
Js memory
PDF
Qt Design Patterns
PDF
Web Application Security
Regexp
Html5 intro
09 performance
Mobile Web Intro
Qt multi threads
Vimperl
Syllabus
Mobile Devices
Network
Architecture app
Cryptography
Unit Testing JavaScript Applications
How to write easy-to-test JavaScript
Introduction to Selenium and Ruby
Introduction To Web Application Testing
Accessibility
Angularjs
Js memory
Qt Design Patterns
Web Application Security

Recently uploaded (20)

PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Empathic Computing: Creating Shared Understanding
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Modernizing your data center with Dell and AMD
PDF
NewMind AI Monthly Chronicles - July 2025
PPTX
Big Data Technologies - Introduction.pptx
PDF
Machine learning based COVID-19 study performance prediction
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
MYSQL Presentation for SQL database connectivity
Advanced methodologies resolving dimensionality complications for autism neur...
Digital-Transformation-Roadmap-for-Companies.pptx
Diabetes mellitus diagnosis method based random forest with bat algorithm
Chapter 3 Spatial Domain Image Processing.pdf
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Network Security Unit 5.pdf for BCA BBA.
Empathic Computing: Creating Shared Understanding
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
20250228 LYD VKU AI Blended-Learning.pptx
Modernizing your data center with Dell and AMD
NewMind AI Monthly Chronicles - July 2025
Big Data Technologies - Introduction.pptx
Machine learning based COVID-19 study performance prediction
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
Per capita expenditure prediction using model stacking based on satellite ima...
MYSQL Presentation for SQL database connectivity

Backbone

  • 1. Backbone.js How to write a well structured multi page web application Thursday, September 12, 13
  • 2. About • Ynon Perek • ynon@ynonperek.com • Find and download slides from: http://ynonperek.com Thursday, September 12, 13
  • 3. Unstructured JS • Developer Starts writing JS code • App gets big, developer gets angry Thursday, September 12, 13
  • 4. What We Want • Build apps like lego • Everything has a place Thursday, September 12, 13
  • 5. JS Solution • Separate Logic from View • Use a framework Thursday, September 12, 13
  • 7. Available JS MV* • And a lot more... • Nice comparison: http://todomvc.com/ Thursday, September 12, 13
  • 8. Backbone.js • Created by Jeremy Ashkenas • Goal: Keep your code AWAY from the DOM Thursday, September 12, 13
  • 9. Reasons Why • Well tested and proven • Strong community • Simple: Almost no magic Thursday, September 12, 13
  • 10. Who’s Using Backbone ? Big list: http://backbonejs.org Thursday, September 12, 13
  • 12. Application Structure • Each “page” is just a div • “Page” can be a full page or partial <body>   <div class="page">     <h1>About Page</h1>   </div>   <div class="page">     <h1>Main Page</h1>   </div>   <div class="page">     <h1>Item Info</h1>   </div>   </body> Thursday, September 12, 13
  • 13. Application Structure • Navigating in the app is just calling a route function • Route function slides divs in-and-out help: function() {   alert('What can I help you with ?'); } Thursday, September 12, 13
  • 14. Application Structure • Implementing Client-side logic • Models “know” • Views “show” Thursday, September 12, 13
  • 15. Application Structure Model View DOM Store Data Renders Data Thursday, September 12, 13
  • 16. Models • Models store your data • Models have no visual representation • Functionality for managing changes Thursday, September 12, 13
  • 17. Views • A View provides the visual representation of a model Task Model Thursday, September 12, 13
  • 18. Collections • Models are usually grouped in collections * Task Model * Task Model * Task Model Daily Tasks Walk the dog Water the plans Thursday, September 12, 13
  • 19. Backbone Benefits • Good separation of concerns • Best for large client- side applications Thursday, September 12, 13
  • 20. What Backbone Is Not • It’s not a framework • So it’s ok to use only parts of it Thursday, September 12, 13
  • 21. What Backbone Is Not • It’s not for small apps that just “show data” • Backbone assumes client-side logic Thursday, September 12, 13
  • 22. What Backbone Is Not • It will never get in your way :) Thursday, September 12, 13
  • 24. Todo App • Model for each task • View for each task • Main application view Thursday, September 12, 13
  • 25. Task Model (function(global) {       global.models.Task = Backbone.Model.extend({         defaults: {             completed: false,             text: ''         }     });   }(this)); Thursday, September 12, 13
  • 26. Task Model (function(global) {       global.models.Task = Backbone.Model.extend({         defaults: {             completed: false,             text: ''         }     });   }(this)); Define a new model Thursday, September 12, 13
  • 27. Task Model (function(global) {       global.models.Task = Backbone.Model.extend({         defaults: {             completed: false,             text: ''         }     });   }(this)); Set default values Thursday, September 12, 13
  • 28. Task View     global.views.TaskView = Backbone.View.extend({         tagName: "div",         className: "task",         events: {             "click" : "handle_click"         }, Define a new View Thursday, September 12, 13
  • 29. Task View     global.views.TaskView = Backbone.View.extend({         tagName: "div",         className: "task",         events: {             "click" : "handle_click"         }, Specify HTML element Thursday, September 12, 13
  • 30. Task View     global.views.TaskView = Backbone.View.extend({         tagName: "div",         className: "task",         events: {             "click" : "handle_click"         }, Define Event Handlers name of a method that will be called when the view is clicked Thursday, September 12, 13
  • 31. View Rendering • render() method of a view is used to render it to HTML • Usually implemented with client side template engine Thursday, September 12, 13
  • 32. Task View         render: function() {             this.$el.html( this.template( this.model.toJSON()));             return this;         },         template: Handlebars.compile($('#task-template').html()) Define Render Function Thursday, September 12, 13
  • 33. Task View         render: function() {             this.$el.html( this.template( this.model.toJSON()));             return this;         },         template: Handlebars.compile($('#task-template').html()) Paint The View onto HTML Thursday, September 12, 13
  • 34. Task View         render: function() {             this.$el.html( this.template( this.model.toJSON()));             return this;         },         template: Handlebars.compile($('#task-template').html()) Handlebars is used as a template engine Thursday, September 12, 13
  • 35. Task View         initialize: function(opts) {             this.model.on('change', this.render, this );         },         handle_click: function() {             if ( this.model.get('completed') ) {                 this.model.set('completed', false);             } else {                 this.model.set('completed', true);             }         }, initialize is called from a view’s constructor Thursday, September 12, 13
  • 36. Task View         initialize: function(opts) {             this.model.on('change', this.render, this );         },         handle_click: function() {             if ( this.model.get('completed') ) {                 this.model.set('completed', false);             } else {                 this.model.set('completed', true);             }         }, We use it to bind event handlers on the model Thursday, September 12, 13
  • 37. Task View         initialize: function(opts) {             this.model.on('change', this.render, this );         },         handle_click: function() {             if ( this.model.get('completed') ) {                 this.model.set('completed', false);             } else {                 this.model.set('completed', true);             }         }, Implementing the clicks handler Thursday, September 12, 13
  • 38. Main App View     global.views.AppView = Backbone.View.extend({         el: $('body'),         events: {             "click .add-btn": "add_task"         },         add_task: function() {             var task_description = this.$el.find('input').val();             var tm = new global.models.Task({ text: task_description });             var tv = new global.views.TaskView({model: tm});             this.$el.find('ul').append(tv.render().el);             this.$el.find('input').val('');         }     }); Thursday, September 12, 13
  • 39. Take Aways • Models keep data • Views show data • Views listen for model changes using on • Views listen for DOM changes using events Thursday, September 12, 13
  • 40. Lab • Add a “Priority” field to a task • Render high priority tasks in red, medium priority tasks in yellow and normal in green Thursday, September 12, 13
  • 41. Backbone Router • A Router connects URL with application state • This allows internal bookmarking and history management Thursday, September 12, 13
  • 42. Hello Router • You only need one • Defines routes and handlers var router = new (Backbone.Router.extend({   routes: {     '' : 'home',     'help' : 'help'   },     home: function() {     alert('WElcome home');   },     help: function() {     alert('What can I help you with ?');   } }))();   Backbone.history.start({ pushState: true } ); Thursday, September 12, 13
  • 43. Changing State • Use router.navigate( url ) to change state • Pass { trigger: true } if you need to also trigger the route Thursday, September 12, 13
  • 44. Demo • Let’s add a View Task page • Shows a specific task in details • Then connect the pages using a router Thursday, September 12, 13
  • 45. Server Side Models How to get server data using Backbone Models Thursday, September 12, 13
  • 46. Models & The Server • Set the urlRoot property of a model to allow it to sync with your server Thursday, September 12, 13
  • 47. Models & The Server Model Id Model Method HTTP Method Url id == 1 .fetch() GET /todos/1 id == 1 .save() PUT /todos/1 no id .fetch() GET /todos no id .save() POST /todos Thursday, September 12, 13
  • 48. Server Events • request event is triggered when sync starts • change event is triggered when an attribute value has changed • sync event is triggered when save is completed (i.e. data is saved on server) Thursday, September 12, 13
  • 49. Server URLs • POST /items => return a new item • GET /items/id => return an existing item by its id • PUT /items/id => change existing item by its id Thursday, September 12, 13
  • 51. Q & A Thursday, September 12, 13
  • 53. Collections • Groups of models • Add/Remove events • Sync from server Thursday, September 12, 13
  • 54. Collections Feed The Zombie Plant The Brainz Do The Zombie Walk Todos Collection Todo Models Thursday, September 12, 13
  • 55. Collection Actions • col.length : number of models in the collection • col.add(m) : add a model • col.remove(m) : remove a model Thursday, September 12, 13
  • 56. Collection Actions • col.at( index ) : get a model at a specific index • col.get( id ) : get a model by its id Thursday, September 12, 13
  • 57. Collection Actions • reset( array_of_models ) : sets the collection’s data Thursday, September 12, 13
  • 58. Collections Demo • Add a Tasks collection • Add a Counter view • Show active tasks count Thursday, September 12, 13
  • 59. Collections     global.models.TasksGroup = Backbone.Collection.extend({         model: global.models.Task     }) Define a new collection A collection needs to create objects, so we must provide the type as a class Thursday, September 12, 13
  • 60. Collection Views • It’s ok to create a view for a collection • Just pass in the collection to the view’s new method • Render delegates its job to subviews • Demo: Create a collection view for TasksGroup Thursday, September 12, 13
  • 61. Collection Views render: function() {   var $el = this.$el;     $el.html('');     this.collection.forEach(function(model) {     var v = new app.views.Task( { model: model } );     $el.append( v.render() );   });     return $el; }, Thursday, September 12, 13
  • 62. Collection Views render: function() {   var $el = this.$el;     $el.html('');     this.collection.forEach(function(model) {     var v = new app.views.Task( { model: model } );     $el.append( v.render() );   });     return $el; }, Pop Quiz: What can go wrong ? Thursday, September 12, 13
  • 63. Managing Subviews • If subviews also listen for model events, you will need to stop listening before removing the container view • Solution: keep a list of subviews in container Thursday, September 12, 13
  • 64. More Collection Views • Same data, different views • Let’s create a counter view • Show total number of tasks Thursday, September 12, 13
  • 65. Collections        initialize: function() {             var cv = new global.views.CounterView( { tasks: this.tasks }).render();             this.$el.append( cv.el );             this.tasks.on('add', cv.render, cv );             this.tasks.on('remove', cv.render, cv);         }, In appview.js Collections trigger events when models are added or removed Thursday, September 12, 13
  • 66. Collections    global.views.CounterView = Backbone.View.extend({         tagName: 'div',         className: 'counter',         initialize: function(opts) {             this.tasks = opts.tasks;         },         render: function() {             console.dir(this.el);             this.$el.html( this.template( { count: this.tasks.length }));             return this;         },         template: Handlebars.compile( $('#counter-template').html() )     }); Thursday, September 12, 13
  • 67. Lab • Modify CounterView so it will also display the number of unfinished tasks Thursday, September 12, 13
  • 68. Other Collection Methods • forEach (function(item) { ... } ) • find • filter • include • toArray Thursday, September 12, 13
  • 69. Collection and Server • Retrieve a collection from the server using fetch() • url is a property of collection • change event is triggered if server state is different Thursday, September 12, 13
  • 70. Collections Server URLs • GET /items => returns all items Thursday, September 12, 13
  • 71. Collection Events • reset event is triggered after fetch() or reset() • add() event is triggered when a model is added to a collection • remove() event is triggered when a model is removed from a collection Thursday, September 12, 13
  • 72. Q & A Thursday, September 12, 13
  • 73. Extending Backbone • Nested Collections • Pagination • Data Binding • Forms Thursday, September 12, 13
  • 74. Extending Backbone • Backbone is easy to extend: • You can add functions to the Backbone namespace • You can override Backbone’s methods Thursday, September 12, 13
  • 75. Try This • Add function toggle() to Backbone.Model to toggle bool values (true / false) Thursday, September 12, 13
  • 76. Try This • Create a TemplateView that acts like a Backbone.View with a simple template rendering functionality built-in Thursday, September 12, 13
  • 77. Backbone Extensions • JS Libs that extend Backbone • Really long list at: https://github.com/jashkenas/backbone/ wiki/Extensions,-Plugins,-Resources Thursday, September 12, 13
  • 78. Nested Collections • A collection that “has” another collection • Example: Inbox and Messages Thursday, September 12, 13
  • 81. Let’s Code This • Models: • Mailbox model • Message model • Collections: • Mailbox collection (for messages) • Folders collection (for mailboxes) Thursday, September 12, 13
  • 82. This works. But... • Given a message item, can you tell in which mailbox it is ? • How do you move a message from one inbox to another ? Thursday, September 12, 13
  • 83. Backbone-Relational • A plugin for managing relations between collections • Adds RelationalModel • http://backbonerelational.org/ Thursday, September 12, 13
  • 84. Q & A Thursday, September 12, 13
  • 85. Pagination • How would you implement pagination ? Thursday, September 12, 13
  • 86. Pagination • Collection only stores partial data • Add methods to collection: • goToNextPage() • goToPreviousPage() • goToPage() Thursday, September 12, 13
  • 87. Pagination • Need to override Backbone.sync to allow sending custom parameters to the server Thursday, September 12, 13
  • 88. Backbone.Sync • sync(method, model, [options]) • method: create / read / update / delete • model: model or collection • options: success and error callbacks Thursday, September 12, 13
  • 89. Backbone.Sync options • Use a global Backbone.sync to enable application wide overriding • Use a model/collection specific sync to have only that collection use your sync Thursday, September 12, 13
  • 90. Backbone.Sync Demo • Let’s write a cacheable model that adds two methods: • cache() • invalidate() • After cache(), all read requests should return the cached copy Thursday, September 12, 13
  • 91. Lab: Fill in the missing parts Backbone.CachedModel = Backbone.Model.extend({   cache: function() {   },     invalidate: function() {   },     sync: function(method, model, opts) {   } }); Thursday, September 12, 13
  • 92. Take Aways • Backbone.sync allows full control on the syncing process • If you just need to add functionality, consider listening for sync events Thursday, September 12, 13
  • 93. Pagination • Use a custom (paginated) collection • Add a sync method so it’ll send your pagination params to the server • AND Someone already did it :) Thursday, September 12, 13
  • 94. The Backbone Way • A special collection is added using the Paginator plugin • Backbone.Paginator.requestPager Thursday, September 12, 13
  • 95. Other Params • Paginated Collection needs: • paginator_core: an object describing how to interact with the server • paginator_ui: an object describing how to display the info • server_api: an object describing the parameters to send • Code: https://github.com/backbone- paginator/backbone.paginator Thursday, September 12, 13
  • 97. Q & A Thursday, September 12, 13
  • 98. Other Plugins • Backbone.localStorage will let you store your models locally https://github.com/jeromegn/ Backbone.localStorage Thursday, September 12, 13
  • 99. Other Plugins • Backbone Forms will automatically create form controls for you • Also adds validation code • https://github.com/powmedia/ backbone-forms Thursday, September 12, 13
  • 100. Other Plugins • Backbone Stickit will let you have two- ways data binding for your views • http://nytimes.github.io/backbone.stickit/ Thursday, September 12, 13
  • 101. Extending Backbone • Extending Backbone is easy • Just create more models, views or controllers • Sometimes you’ll need to override Backbone methods Thursday, September 12, 13
  • 102. Benefits • Lifts big apps • Scalable and very stable • No magic • Extensible Thursday, September 12, 13
  • 103. Dark Side • Not suitable for small apps • Can be confusing for new developers • Can sometimes add clutter Thursday, September 12, 13
  • 104. Thank You • Ynon Perek • me@ynonperek.com • ynonperek.com Thursday, September 12, 13