Created
December 2, 2011 00:03
-
-
Save datapimp/1420852 to your computer and use it in GitHub Desktop.
General Architecture Considerations for a Backbone.js / Socket.IO App
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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