Slide 1

Slide 1 text

New Dog, Old Tricks (Or: Dojo Already Did That) Rebecca Murphey @rmurphey Backbone Conf 2012 Friday, June 1, 12 rebecca, js dev at bocoup slex warned me i’d have people coming after me with pitchforks for this title, but i think you’ll be ok

Slide 2

Slide 2 text

Friday, June 1, 12 started playing with backbone just a couple of months ago after working with dojo for > 2 years its data stuff is pretty powerful -- especially if your data fits neatly into a RESTful CRUD interface, which turns out is kinda hard for some stuff, but whatever its views on the other hand ... there’s some event delegation stuff, and an empty render method, and otherwise glwtd coming from the dojo world, this was hard to come to terms with. the whole thing that seduced me about dojo was its templated widgets

Slide 3

Slide 3 text

define([ 'dijit/_WidgetBase', 'dijit/_TemplatedMixin', 'text!./my-template.html' ], function(_Widget, _Templated, tmpl) { return dojo.declare([ _Widget, _Templated ], { templateString : tmpl, postMixInProperties : function() { this.clicks = 0; }, postCreate : function() { this.connect(this.buttonElement, 'click', '_onButtonClick'); }, _onButtonClick : function(e) { e.preventDefault(); console.log(++this.clicks); this.onButtonClick(this.clicks); }, onButtonClick : function(clickCount) { } }); }); Friday, June 1, 12 so in dojo land, a view -- a “widget” -- might look like this

Slide 4

Slide 4 text

${title}

${body}

Click me!
Friday, June 1, 12 plus a template that looks like this (it’s pretty easy to switch templating engines)

Slide 5

Slide 5 text

require([ 'widgets/my-widget.js' ], function(MyWidget) { new MyWidget({ title : 'My Widget', body : 'So simple!' }).placeAt(document.body, 'only'); }); Friday, June 1, 12 and then we’d use it like this there are some cool things here, and i missed them when i started using backbone’s views

Slide 6

Slide 6 text

define([ 'dijit/_WidgetBase', 'dijit/_TemplatedMixin', 'text!./my-template.html' ], function(_Widget, _Templated, tmpl) { return dojo.declare([ _Widget, _Templated ], { templateString : tmpl, postMixInProperties : function() { this.clicks = 0; }, postCreate : function() { this.connect(this.buttonElement, 'click', '_onButtonClick'); }, _onButtonClick : function(e) { e.preventDefault(); console.log(++this.clicks); this.onButtonClick(this.clicks); }, onButtonClick : function(clickCount) { } }); }); Friday, June 1, 12 default rendering logic -- you provide a template, and dojo knows how to turn it into a document fragment using your view’s data

Slide 7

Slide 7 text

${title}

${body}

Click me!
Friday, June 1, 12 dojo’s widgets also let you indicate in your template that you’d like your view code to have a reference to a given element

Slide 8

Slide 8 text

define([ 'dijit/_WidgetBase', 'dijit/_TemplatedMixin', 'text!./my-template.html' ], function(_Widget, _Templated, tmpl) { return dojo.declare([ _Widget, _Templated ], { templateString : tmpl, postMixInProperties : function() { this.clicks = 0; }, postCreate : function() { this.connect(this.buttonElement, 'click', '_onButtonClick'); }, _onButtonClick : function(e) { e.preventDefault(); console.log(++this.clicks); this.onButtonClick(this.clicks); }, onButtonClick : function(clickCount) { } }); }); Friday, June 1, 12 if you want to hook into the “lifecycle” of a view -- the default logic dojo uses to create a view -- there are lifecycle methods you can use to affect the process without modifying the core logic

Slide 9

Slide 9 text

define([ 'dijit/_WidgetBase', 'dijit/_TemplatedMixin', 'text!./my-template.html' ], function(_Widget, _Templated, tmpl) { return dojo.declare([ _Widget, _Templated ], { templateString : tmpl, postMixInProperties : function() { this.clicks = 0; }, postCreate : function() { this.connect(this.buttonElement, 'click', '_onButtonClick'); }, _onButtonClick : function(e) { e.preventDefault(); console.log(++this.clicks); this.onButtonClick(this.clicks); }, onButtonClick : function(clickCount) { } }); }); Friday, June 1, 12 dojo’s widgets also provide `this.connect`, which handles standard event binding *and* binding to arbitrary methods of arbitrary objects -- all with teardown that avoids memory leaks of course, backbone’s standard event delegation stuff takes care of this for delegate-able DOM events, but it’s a different story when you’re binding to models/collections

Slide 10

Slide 10 text

require([ 'widgets/my-widget.js' ], function(MyWidget) { new MyWidget({ title : 'My Widget', body : 'So simple!' }).placeAt(document.body, 'only'); }); Friday, June 1, 12 finally, dojo’s widgets give you a nice way to place them where you want

Slide 11

Slide 11 text

Friday, June 1, 12 here’s another picture of my dog i don’t mean that backbone should add all this i mean that *you should be aware of these techniques and add them as you see fit*

Slide 12

Slide 12 text

rendering serializing, templatizing, placing binding memory-safe setup & teardown lifecycle react when things happen Friday, June 1, 12 my solution: create my own “SuperView” that gives me some help with these things goal: - don’t make me think! - don’t let different teammates solve the same problem in different ways - avoid repetition - solve a problem well and solve it in a single place

Slide 13

Slide 13 text

Friday, June 1, 12 backbone is uncut stone; it’s up to you to carve it into the form that makes sense for your project you shouldn’t feel obligated to use it as-is even if you don’t want to *use* one of the other tools, you do well to learn what they offer, and incorporate what makes sense

Slide 14

Slide 14 text

github.com/rmurphey/srchr-demo pinboard.in/u:rmurphey/t:new-dogs-old-tricks/ Friday, June 1, 12

Slide 15

Slide 15 text

rmurphey.com • @rmurphey • bocoup.com Friday, June 1, 12 rebecca, sr js dev at bocoup