Backbone.js + DjangoLeah CulverPyCodeConf 2011
View Slide
Convoretopic-based chat on the web
Leafy Chatweb-based IRC client
GroveIRC for your company
chat UI
Leafy Chat - pure JavaScript
$('#message-form-sender').submit(Leafy.sendMessage)
sendMessage: function(e) {var msg = $('#message').val()var row = '' + currentUser + ': ' + msgrow = row + '' + ts + ''$(Leafy.channelID(channel)).append(row)Kahlan.say(Leafy.currentChannel, msg)},
this.socket = new Orbited.TCPSocketsay: function(channel, msg) {var data = {to: channel, type: 'privmsg', body: msg}this.socket.send(JSON.stringify(data) + "\r\n")},
1. handle form submit2. create new message3. display message in list4. POST message via AJAX
Grovegrove.io/app
backbone.js
MVC
MVCMTV
Model
window.Message = Backbone.Model.extend ({});
Collection
window.MessageCollection = Backbone.Collection.extend ({model: Message,});
Views
1. handle form submit
window.MessageFormView = Backbone.View.extend ({events: {'submit form': 'submitForm',},});
2. create new message
submitForm: function() {var msg = $('#message).val();var message = new Message ({'message': msg,});
3. display message in list
currentChannel.messages.add(message);
window.MessageListView = Backbone.View.extend({model: MessageCollection,initialize: function() {this.model.bind('add', this.addMessage);this.model.bind('change', this.render);this.model.bind('remove', this.removeMessage);},
4. POST message via AJAX
currentChannel.messages.create({'message': msg}, {success: function(model, response) {message.set(model.attributes, { silent: true });},error: function(model, error) {currentChannel.messages.remove(message);$('#message').val(msg);}});
Templates
<br/><span>{{user.username}}</span>: {{message}}<br/><span class="ts">{{timestamp date_created}}</span><br/>
Handlebars.js
template: Handlebars.compile($('#msg-template').html())
{% include_raw "message.html" %}djangosnippets.org/snippets/1684
additional goodies
Sync
url: function() {return this.channel.url() + '/messages/';},
url(r'^app/channels/(?P\d+)/messages/$','channel_messages'),
if request.method == 'POST':json_data = simplejson.loads(request.raw_post_data)message = Message.objects.create(message=json_data.get('message'),...)return JSONResponse(request, message.data())
https://gist.github.com/1265346
Events
App.trigger('messageAdded', channel);
initialize: function() {App.bind('messageAdded', this.messageAdded);},messageAdded: function(channel) {// Do something...}
Router
var MainRouter = Backbone.Router.extend({routes: {'app/join': 'join','app/:name': 'channel'},join: function() {var joinPageView = new JoinPageView();return joinPageView.loadPage();},});
Questions?
Photoshttp://www.flickr.com/photos/coldtaxi/426162862/http://www.flickr.com/photos/aliaholle/5888906660/http://www.flickr.com/photos/joshmaz/5248178452/http://www.flickr.com/photos/1stpix_diecast_dioramas/5934583890/http://www.flickr.com/photos/hamed/429069420/http://www.flickr.com/photos/ittybittiesforyou/4942706804/http://www.flickr.com/photos/krhamm/171302278/http://www.flickr.com/photos/vinothchandar/5148046888/http://www.flickr.com/photos/jliba/4437937329/http://www.flickr.com/photos/seier/2034873075/http://www.flickr.com/photos/31246066@N04/5115966185/sizeshttp://thefilmstage.com/news/zoolander-2-in-limbo-at-paramount/http://www.flickr.com/photos/byebyeempire/323372590/http://www.flickr.com/photos/shakethesky/4104894504/http://www.flickr.com/photos/litlnemo/3296421032/http://www.flickr.com/photos/qusic/3370510628/