Slide 1

Slide 1 text

Backbone.js + Django Leah Culver PyCodeConf 2011

Slide 2

Slide 2 text

Convore topic-based chat on the web

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Leafy Chat web-based IRC client

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

Grove IRC for your company

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

chat UI

Slide 9

Slide 9 text

Leafy Chat - pure JavaScript

Slide 10

Slide 10 text

$('#message-form-sender').submit(Leafy.sendMessage)

Slide 11

Slide 11 text

sendMessage: function(e) { var msg = $('#message').val() var row = '' + currentUser + ': ' + msg row = row + '' + ts + '' $(Leafy.channelID(channel)).append(row) Kahlan.say(Leafy.currentChannel, msg) },

Slide 12

Slide 12 text

this.socket = new Orbited.TCPSocket say: function(channel, msg) { var data = {to: channel, type: 'privmsg', body: msg} this.socket.send(JSON.stringify(data) + "\r\n") },

Slide 13

Slide 13 text

1. handle form submit 2. create new message 3. display message in list 4. POST message via AJAX

Slide 14

Slide 14 text

Grove grove.io/app

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

backbone.js

Slide 17

Slide 17 text

MVC

Slide 18

Slide 18 text

MVC MTV

Slide 19

Slide 19 text

Model

Slide 20

Slide 20 text

window.Message = Backbone.Model.extend ({ });

Slide 21

Slide 21 text

Collection

Slide 22

Slide 22 text

window.MessageCollection = Backbone.Collection.extend ({ model: Message, });

Slide 23

Slide 23 text

Views

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

1. handle form submit

Slide 28

Slide 28 text

window.MessageFormView = Backbone.View.extend ({ events: { 'submit form': 'submitForm', }, });

Slide 29

Slide 29 text

2. create new message

Slide 30

Slide 30 text

submitForm: function() { var msg = $('#message).val(); var message = new Message ({ 'message': msg, });

Slide 31

Slide 31 text

3. display message in list

Slide 32

Slide 32 text

currentChannel.messages.add(message);

Slide 33

Slide 33 text

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); },

Slide 34

Slide 34 text

4. POST message via AJAX

Slide 35

Slide 35 text

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); } });

Slide 36

Slide 36 text

Templates

Slide 37

Slide 37 text

<span>{{user.username}}</span>: {{message}} <span class="ts">{{timestamp date_created}}</span>

Slide 38

Slide 38 text

Handlebars.js

Slide 39

Slide 39 text

template: Handlebars.compile($('#msg-template').html())

Slide 40

Slide 40 text

{% include_raw "message.html" %} djangosnippets.org/snippets/1684

Slide 41

Slide 41 text

additional goodies

Slide 42

Slide 42 text

Sync

Slide 43

Slide 43 text

url: function() { return this.channel.url() + '/messages/'; },

Slide 44

Slide 44 text

url(r'^app/channels/(?P\d+)/messages/$', 'channel_messages'),

Slide 45

Slide 45 text

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())

Slide 46

Slide 46 text

https://gist.github.com/1265346

Slide 47

Slide 47 text

Events

Slide 48

Slide 48 text

App.trigger('messageAdded', channel);

Slide 49

Slide 49 text

initialize: function() { App.bind('messageAdded', this.messageAdded); }, messageAdded: function(channel) { // Do something... }

Slide 50

Slide 50 text

Router

Slide 51

Slide 51 text

var MainRouter = Backbone.Router.extend({ routes: { 'app/join': 'join', 'app/:name': 'channel' }, join: function() { var joinPageView = new JoinPageView(); return joinPageView.loadPage(); }, });

Slide 52

Slide 52 text

Questions?

Slide 53

Slide 53 text

Photos http://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/sizes http://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/