viking academy backbone.js
DESCRIPTION
Introduction to backbone.jsTRANSCRIPT
and single-page web apps
http://backbonejs.org/
Bert Wijnants - Mobile Vikings - 9 november 2012
backbone.js
Let's start with a little historyJavascript was invented by Netscape in 1995,and the web looked like...
iteractive website:<marquee>, <blink>
the rise of AJAX (2004)
gmail is the first single-page web app
more and more javascript
a website is:lots of html pages with some javascriptajax returns html
a webapp is:lots of javascript with some html pagesajax returns json
front-end is taking over program logicnecessary to create highly responsive user interfaces
6 in top 7 on Github is javascript
#7
Why another framework?we've got jQuery, right?
What's wrong with jQuery?
jQuery is very useful for DOM manipulations, events, ajax,... (cross-browser)and btw: use zepto.js for mobile devices (webkit only)
DOM manipulation = very expensive taskbreaks hardware accelerationalways avoid unnecessary DOM manipulationsespecially on mobile devices
Too easy to use the DOM for state of your app
How to avoid DOM manipulations?
important ruleThe DOM is write-only!
don't use it to store the state of your appit's for presentation purposes only
Bad:
$(".button").click( function(event) {if (!$(this).hasClass("selected")) {
$(this).parent().find(".button.selected").removeClass("selected);$(this).addClass("selected")
}});
Don't read from the DOM to know which of the buttons is selected
But where to store everything if DOM is not allowed?Here backbone.js kicks in...
every good framework has "a sentence" :-)
Backbone.js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.
Single-page web apps with hundreds of lines of javascript. Most apps just give structure with namespaces:
var namespace = (function() {return {
....}
})();
backbone.js
We need more structure than this!
backbone.js
Pretty maturestarted 2 years agopopular on githubversion 0.9.2, 1.0 coming upfrom the creators of underscore.js and coffeescript
Lightweightjust 2 dependencies: underscore, jquery/zepto
Also runs on node.jsSame models in front-end and back-end
Annotated source
MVC framework or whatever
it's not really MVC, it's MVVM!
ModelViewViewModel (=DOM)
where is the controller? skinny controller, fat modelprogram logic in models and views
DOM Model
javascripthtml
MODELis the only source of truth!is pure javascriptModels and CollectionsCollection is an array of Models
Events
Lots of events are firedwith these naming conventions:"add" (model, collection) — when a model is added to a collection."remove" (model, collection) — when a model is removed from a collection."reset" (collection) — when the collection's entire contents have been replaced."change" (model, options) — when a model's attributes have changed."change:[attribute]" (model, value, options) — when a specific attribute has been updated."destroy" (model, collection) — when a model is destroyed."sync" (model, collection) — triggers whenever a model has been successfully synced to the server."error" (model, collection) — when a model's validation fails, or a save call fails on the server."route:[name]" (router) — when one of a router's routes has matched."all" — this special event fires for any triggered event, passing the event name as first argument.
DOM View Model
javascripthtml
change datahtml events
render change events
VIEWobserves model changesis pure javascriptrender function to write to DOMthis.el is the element in DOMobserves events from DOM(click, touchmove, ...)
Model-backed viewsvar model = new Todo({
title: 'foo', done: false
});var view = new TodoView(model);
View has direct access to model.Model does not. View listens to change events.
Persistency a.k.a the database
javascript applications usually work like this:
get_all()get_one()save_one()update_one()delete_one()
and the same on server-side: CRUDLots of code for repetitive operations
Sync
Backbone.js has a sync module
CRUD interfaceGET /modelGET /model/<id>POST /modelUPDATE /model/idDELETE /model/id
can be overwritten granularly. examples:use localstorage for all fetch operationsuse sockets instead of REST over http
SYNCasynchronous persistency
DOM View Model
javascripthtml
change datahtml events
render change events
web service
sync
Model.sync
In a Model or Collection:fetch()save()remove()
don't care about what's going on in the back
More stuff:
Model validation on client-sideyou can only save() a valid model
Routereasy url handling (with # or #!)works with History API, so back button works
Underscore functionsmap, reduce, for each, client-side templates, ...
example: Model
var Todo = Backbone.Model.extend({defaults: {
"title" : "(empty)","done" : false
},toggle: function() {
this.set({"done" : !this.get("done")
});this.save();
},clear: function() {
this.destroy();}
});
example: Collectionvar TodoList = Backbone.Collection.extend({
model: Todo,
initialize: function() {this.fetch();
},
done: function() { return this.filter(function(todo){ return todo.get('done'); });},
remaining: function() { return this.without.apply(this, this.done());},
});
example: Viewvar TodoView = Backbone.View.extend({
tagName: "li",template: Templates.todo,
initialize: function() {this.model.bind('change', this.render, this);this.model.bind('destroy', this.remove, this);
},render: function() {
this.$el.html(this.template(this.model.toJSON()));this.$el.toggleClass('done', this.model.get('done'));return this;
}});
example: View (continued)events: { "click .toggle" : "toggleDone", "click .clear" : "clear"},
toggleDone: function() {this.model.toggle();
},
clear: function() {this.model.clear();
}
Problems
Syntax is not very clearLots of ( { "=> coffeescript can help with this
The use of thisyou loose scope quite easily in javascript=> var self = this to the rescue
Steep learning curvebut documentation is very goodlots of support on stackoverflow
Advantages
structured javascriptwrite-only DOMdesigned for web appssyncing with back-end = trivialnaming conventions (events, render, ...)model change => view rendervery popular: big community
Getting started
http://backbonejs.orgEverything you need is here
Or check out the webapp for VikingSpots NG:github.com/deals-platform/mobile-apps/html5
Questions? Remarks?