Skip to content

Instantly share code, notes, and snippets.

@datapimp
Created December 2, 2011 00:03
Show Gist options
  • Select an option

  • Save datapimp/1420852 to your computer and use it in GitHub Desktop.

Select an option

Save datapimp/1420852 to your computer and use it in GitHub Desktop.
General Architecture Considerations for a Backbone.js / Socket.IO App
# There should be a viewport class
# which watches over the whole area
# of your single page app. global events
# can be handled here.
Viewport = Backbone.View.extend
el: "#top-most-container"
StateMachine = Backbone.Model.extend
initialize: (@attributes)->
# we have our main application
class Application
constructor: (@options)->
_.extend @, Backbone.Events
# use backbone's model for storing
# state. you could even synchronize
# state with the server this way, or
# use the LocalStore class documented later
@state = new StateMachine
# this allows us to run callbacks whenever
# some state changes in the application as a whole
@state.bind "change:whatever", @onWhateverChange
# the socket manager will be detailed below
@socket = new SocketManager()
set: (attribute, value)-> @state.set(attribute, value)
get: (attribute)-> @state.get(attribute)
# in the app, you can bind to change events in the state
# model, and act accordingly
onWhateverChange: ()->
# create a global / window instance of the application class
$ ->
window.MyApp = new Application()
# now on to the good parts
class SocketManager
constructor: (@options)->
_.extend @, Backbone.Events
_.bindAll @, "relayer"
@bind_to_socket()
# the socket.io server will be emitting
# events over the socket. a very clean way
# of handling these events is to just have
# the socket send an array with [event_name='', event_args={}]
bind_to_socket: ()-> @socket.on "relay", @relayer
# any events which get relayed over the socket, will be emitted
# with its arguments by the socket manager instance
relayer: (data) ->
[event, args] = JSON.parse(data)
@trigger event, args
# a local store is similar to a table in a normal database.
# it is a way of organizing, storing, retrieving, updating
# backbone models in localStorage. Models are stored against
# a GUID. You can sync the models based on a shared GUID on
# your server side data store
class LocalStore
constructor: (@name)->
store = localStorage.getItem(@name)
@data = ( store && JSON.parse(store) ) || {}
guid: ()->
S4 = ()-> (((1+Math.random())*0x10000)|0).toString(16).substring(1)
(S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4())
# serialize the store into JSON and put it in the localStorage
save: ()->
localStorage.setItem(@name, JSON.stringify(@data) )
# create a model in the table
create: (model)->
model.id = model.attribtues.id = @guid() unless model.id
@data[ model.id ] = model
@save()
model
update: (model)->
@data[model.id] = model
@save()
model
find: (model)-> @data[ model.id ]
findAll: ()->
_.values( @data )
destroy: (model)->
delete @data[ model.id ]
@save()
model
# All models, collections delegate to Backbone.Sync for their
# persistence layer. We can store in localStorage instead.
Backbone.Sync = (method, model, options)->
store = model.localStorage || model.collection.localStorage
resp = switch method
when "read" then (if model.id then store.find(model) else store.findAll())
when "create" then store.create(model)
when "update" then store.update(model)
when "delete" then store.destroy(model)
if resp
options.success(resp)
else
options.error("Record not found")
# You will need to develop your own means of syncing the localStorage items
# with your back end database
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment