$30 off During Our Annual Pro Sale. View Details »

New Dogs, Old Tricks (Or: Dojo Already Did That)

New Dogs, Old Tricks (Or: Dojo Already Did That)

Backbone may be the current app development hotness, and its tiny size and focused mission stand in stark contrast to the more comprehensive philosophy of the Dojo toolkit, but developers using the new(ish) kid on the block could learn a few things from the battle-tested patterns of Dojo's templated widgets, especially when it comes to working with views. In this talk, we'll look at how we can add evented views, smarter binding and teardown, view lifecycle methods, production-optimized template support, and dependency management to Backbone apps.

Rebecca Murphey

June 01, 2012
Tweet

More Decks by Rebecca Murphey

Other Decks in Technology

Transcript

  1. 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

    View Slide

  2. 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

    View Slide

  3. 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

    View Slide


  4. ${title}
    ${body}
    Click me!

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

    View Slide

  5. 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

    View Slide

  6. 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

    View Slide


  7. ${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

    View Slide

  8. 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

    View Slide

  9. 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

    View Slide

  10. 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

    View Slide

  11. 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*

    View Slide

  12. 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

    View Slide

  13. 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

    View Slide

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

    View Slide

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

    View Slide