Using the Flatiron framework's router Director with Backbone.JS and how it addresses key issues encountered by complex single-page web applications in a simple & effective way.
2. WHO AM I?
• Lead Front-End Dev at Thefuture.fm (formerly Dubset)
• Columbia University MS in Computer Science
Vision/Graphics track w/ focus in UI/UX
• What is Thefuture.fm?
Curated internet radio
Endless streaming mixes from top DJs around the world
Single-Page Web App using Backbone.js
• Worked with Charlie Robbins (github.com/indexzero) & Paolo
Fragomeni(github.com/hij1nx) of Nodejitsu (jit.su) on integrating flatiron/director
with our Backbone app in the early pre-1.0 days
3. WHAT’S THIS ALL ABOUT?
• My Main Focus:
• Client-Side router implementation
• Comparing Director and Backbone.Router side-by-side
• Why I chose Director over Backbone’s built-in Router
• How to unplug Backbone.Router and plug in Director instead
• Background Items:
• What is Backbone.JS?
• Intro to Backbone.Router
• What is Flatiron?
• Intro to Flatiron’s Director
OK LET’S GET STARTED!!
4. WHAT IS BACKBONE.JS?
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.
Model
Represents interactive data
Defines logic surrounding it
Provides functionality to manage changes
Collection
A collection of models
Ordered!! (can define Collection.comparator)
View
Logical view backed by a model/collection
Freeform & non-restrictive – works with any JS templating library
Router
Simple client-side routing
Determines what code to run (i.e. rendering a view) when a URL (route) is hit
Dependencies: Underscore.js, json2.js, jQuery/etc.
documentcloud.github.com/backbone
5. BACKBONE.JS PROVIDES STRUCTURE
MVP FRAMEWORK
MODEL: defines data & stores its current state
VIEW: presents data & routes user input to Presenter
PRESENTER: drives changes to Model & View
MODEL PRESENTER VIEW
show Backbone.Model Backbone.View Templates/
index (Backbone.Collection) Rendered View
• Provides structure for your data that you can parallel with your views
(keeps things logically organized)
documentcloud.github.com/backbone
6. BACKBONE.JS EVENT HANDLING
Models/Collections trigger events which Views can bind to.
Collection
reset(collection) - when the entire contents have been replaced
triggered by: fetch, reset, etc.
add(model, collection) - when a model is added to a collection
remove(model, collection) - when a model is removed from a collection
Model
change(model, options) – when a model’s attributes have changed
change:[attribute](model, value, options) – when a specific attribute has been updated
Some notes:
{silent: true}
.trigger(“[event]”)
• Syncs your views consistently with the data that drives it using rich event handling
documentcloud.github.com/backbone
7. BACKBONE.ROUTER: QUICK INTRO
Routing determines what code to run for a specified URL.
var myRouter = Backbone.Router.extend({ To start tracking hashchanges:
routes: { Backbone.history.start();
“/”: “home”,
“/djs/:permalink”: “djs”,
define
route table
“/djs/:permalink/:mixid”: “djs”
}, URL fragments fn names
home: function() { … }, define
djs: function(permalink, mixid) { … } functions
});
SIMPLE! Great for straightforward client-side routing of simple web apps.
documentcloud.github.com/backbone
8. WHAT IS FLATIRON?
Flatiron is an adaptable framework for building modern web applications. It was built
from the ground up for use with Javascript and Node.js.
Philosopy
No one agrees on frameworks. It's difficult to get consensus on how much or how
little a framework should do. Flatiron's approach is to package simple to use yet full
featured components and let developers subtract or add what they want.
Motivation
Build a collection of decoupled, unobtrusive tools that can operate as well in unison
as they do independently. Promote code organization and sustainability by clearly
separating development concerns.
flatironjs.org
9. FLATIRON: MAIN COMPONENTS
1. DIRECTOR URL Routing Client-Side!!
2. PLATES Templating
3. RESOURCEFUL Data Management
4. UNION Middleware
5. BROADWAY Plugins
6. WINSTON Logging
flatironjs.org
10. WHAT IS DIRECTOR?
http://github.com/flatiron/director
Synopsis
Director is a router. Routing is the process of determining what code to run
when a URL is requested.
Motivation
A routing library that works in both the browser and node.js environments
with as few differences as possible. Simplifies the development of Single
Page Apps and Node.js applications. Dependency free.
flatironjs.org
11. DIRECTOR: OVERVIEW
• Depth-first search URL Matching
• Route events
• global
• for each route
• Nested routing
• Route recursion
• Regex
• Lots of flexibility
• function organization
github.com/flatiron/director
12. DIRECTOR: QUICK INTRO
ROUTE TABLE CONSTRUCTOR
var routes = { // instantiate
'/': viewMethods.index,
var router = new Router(routes)
'/dog': {
.configure(options);
'/:color': {
on: function (color) { // initialize – start listening!
console.log(color) router.init();
}
}
}
};
github.com/flatiron/director
13. DIRECTOR > BACKBONE.ROUTER
WHY BACKBONE.ROUTER
DIRECTOR SAVES THE DAY!
WASN’T CUTTING IT FOR US
- Custom styling FLEXIBILITY
- “Sectional” routing - Routing Events: Setup/Teardown
- Global routing events
- Pre-route authorization
- notfound handler à 404 Page
- Global event firing
- Nested Routes & Recursion
- Proper 404 catching
- Regex control
- More flexibility
- Flexibility with function
organization
14. DIRECTOR: ROUTING EVENTS
// instantiate the router w/ global
• ON/AFTER = SETUP/TEARDOWN events
var myRouter = new
• Custom Formatting Router(routes).configure({
• Authorization Issues on: analyticsEvents,
Global after: cleanupView,
• “Sectional” setup/teardown events notfound: render404 404!!
• Global routing events: }).init();
Reporting on every route
View cleanup after every route FUNCTION DEFINITION:
var branded = {
hugoBoss: {
ROUTING TABLE [snippet]: setup: function() {
'/hugoboss': {
$('body').addClass('hugo-boss'); Setup
BACKBONE VIEW new HugoBossView();
on: branded.hugoBoss.setup, },
teardown: function() {
after: branded.hugoBoss.teardown Teardown! $('body').removeClass('hugo-boss’);
}
}
}
};
15. DIRECTOR: NESTED ROUTING & RECURSION
1. Organized routes DIRECTOR: recursion forward!
2. Less repetition ‘/section’: {
3. “Sectional” routing on: function() {
4. Recursive routing Check for authorization if(!userLoggedIn) {
// route to ‘/login’
BACKBONE:
Break out of recursion return false;
“section”: “section”,
}
“section/sub1”: “sectionSub1”,
“section/sub2”: “sectionSub2”, },
“section/sub3”: “sectionSub3” ‘/sub1’: ...,
... ‘/sub2’: ...,
OR:
}
“section/:sub”: “section”
... Define logic with cases in “section”
function definition
16. DIRECTOR: FLEXIBLITY & CONTROL
REGULAR EXPRESSIONS FUNCTIONAL ORGANIZATION
DIRECTOR: BACKBONE.ROUTER:
var router = Router({ var Workspace = Backbone.Router.extend({
routes: {
// given the route '/hello/world'.
"help": "help", // #help
'/hello': {
"search/:query": "search", // #search/
Regex '/(w+)': {
kiwis
yay! },
// this function will return 'world'.
help: function() { ... },
on: function (who) { console.log(who) } search: function(query) { ... }
} });
}
});
DIRECTOR:
- Organize functions into global, views, custom
- Nested function definitions to parallel nested
route definitions
17. HOW TO REPLACE BACKBONE.ROUTER WITH DIRECTOR
• What we don’t need from Backbone.js
- Backbone.Router
- Backbone.History (tracks hashchange events)
• Instead of:
var myRouter = Backbone.Router.extend({ … });
Backbone.history.start();
• We want:
var myRouter = new Router(routingTable);
myRouter.init();
WHY SO EASY!! J