116
JAVASCRIPT BEST PRACTICES & BACKBONE.JS FOR THE PHP DEVELOPER Ryan Weaver @weaverryan Thursday, May 24, 12

JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Embed Size (px)

DESCRIPTION

Time to talk your JavaScript to the next level. Join us as we take a normal jQuery document.ready block and start to break it into objects, use the prototype model, investigate scope, and self-executing JavaScript blocks.We'll be guided in our journey by Mario and his friends, as well as a full-demo and source code, complete with a poor-man's animation of Luigi kicking ass with a fireball. We'll also run through the basics of Backbone.js and which parts to use and avoid based on your application.And because you're a PHP developer, we'll see how JavaScript object-oriented principles would look like if they were written in PHP.http://weaverryan.github.com/php-js-playground/https://github.com/weaverryan/php-js-playground

Citation preview

Page 1: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

JAVASCRIPT BEST PRACTICES & BACKBONE.JS FOR THE PHP DEVELOPER

Ryan Weaver@weaverryan

Thursday, May 24, 12

Page 2: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

7 tips for writing JavaScript like a jerk

+What to take and leave in

Backbone.js

Thursday, May 24, 12

Page 3: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Who is this dude?• Co-author of the Symfony2 Docs

• KnpLabs US - Symfony consulting, training, Kumbaya

• Writer for KnpUniversity.comscreencasts

• Fiancee of the much more talented @leannapelham -----> June 9th, 2012!

http://www.knplabs.com/enhttp://www.github.com/weaverryan@weaverryan

Thursday, May 24, 12

Page 4: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Chapter 1: Java$criptQuery

Look mom, I’m a JavaScript professional

@weaverryanThursday, May 24, 12

Page 5: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

1. jQuery(document).ready(...)2. 1500 lines, with deeply nested anonymous functions3. Profit! $$$

@weaverryanThursday, May 24, 12

Page 6: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

@weaverryan

Too soon?... sry fb, luv u kthxbye

Thursday, May 24, 12

Page 7: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

The brains behind this presentation...

Thursday, May 24, 12

Page 8: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

source:http://www.geeky-gadgets.com/super-mario-bros-matryoshka-dolls/

Thursday, May 24, 12

Page 9: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Thursday, May 24, 12

Page 10: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

<div class="mario box"> .mario <div class="luigi box"> .luigi <div class="kick-butt">...</div> <a href="#" class="peach box"> .peach </a> </div></div>

Thursday, May 24, 12

Page 11: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

jQuery(document).ready(function() { var $luigi = $('.event-details .luigi');

$luigi.click(function() { $(this).addClass('active'); return false; });});

Let’s kick some arse!

Thursday, May 24, 12

Page 12: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

DEMO!!!!!

0 - The starting point

http://bit.ly/php-js-demo

Thursday, May 24, 12

Page 13: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Princess Pro-tip

Instead of listening to this guy drone on, just find, fork and play with the code

yourself!

http://bit.ly/php-js-play

Thursday, May 24, 12

Page 14: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

‣ Click either .luigi or .peach‣ the .luigi wrapper gets the active class

Thursday, May 24, 12

Page 15: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Mario’s bad JavaScript tip #1:

Ignore the jQuery “event” object, it’s probably stupid...

@weaverryan

http://bit.ly/php-js-demo01 - The jQuery Event

Thursday, May 24, 12

Page 16: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Events happen

Thursday, May 24, 12

Page 17: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Click!

Event

1) You click!2) An event travels up the tree

Thursday, May 24, 12

Page 18: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Browser eventversus

jQuery event

‣ The browser event contains all the information about what happened

‣the jQuery event cleans up cross-browser compatibility ugliness

Thursday, May 24, 12

Page 19: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

$luigi.click(function(event) { // ...});

‣ event.target: The actual element that received the click

‣ event.currentTarget: The element that this listener was attached to

Thursday, May 24, 12

Page 20: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

$luigi.click(function(event) { // ...});

Our listener is registeredon .luigi

Thursday, May 24, 12

Page 21: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

If you click .peach:event.target: .peachevent.currentTarget: .luigi

Thursday, May 24, 12

Page 22: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

If you click .luigi:event.target: .luigievent.currentTarget: .luigi

Thursday, May 24, 12

Page 23: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

event.currentTarget

==

this

* unless you screw with scope, which we’ll see!

Thursday, May 24, 12

Page 24: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

$luigi.click(function(event) { // these are the same! $(event.currentTarget) .addClass('active'); $luigi.addClass('active');});

Thursday, May 24, 12

Page 25: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Preventing the damn “#” on the URL

$luigi.click(function() { $(this).addClass('active'); return false;});

Thursday, May 24, 12

Page 26: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Princess Pro-tip

return false stops propagation, and is a great way to screw

with your teammate’s events

http://fuelyourcoding.com/jquery-events-stop-misusing-return-false/

Thursday, May 24, 12

Page 27: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

$luigi.click(function(event) { event.preventDefault();

// ...});

... but if you like your coworkers...

The event keeps traveling up the DOM

Thursday, May 24, 12

Page 28: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Bad JavaScript moral #1:

jQuery’s event object is a dangerous source of useful

information and control

@weaverryanThursday, May 24, 12

Page 29: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Mario bad JavaScript tip #2:

Avoid using objects: they threaten to organize your code...

and are creepy...

@weaverryan

http://bit.ly/php-js-demo02 - Basic jQuery Objects

Thursday, May 24, 12

Page 30: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

A PHP object

@weaverryanThursday, May 24, 12

Page 31: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

<?php

class MagicBoxes{ public function initializeClick($wrapper) { // ... }}

$magicBoxes = new MagicBoxes();$magicBoxes->initializeClick('something');

Thursday, May 24, 12

Page 32: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

A JavaScript object

@weaverryanThursday, May 24, 12

Page 33: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

var MagicBoxes = { someProperty: 0,

initializeClick: function($container) { // ... }};

MagicBoxes.initializeClick(something);

Thursday, May 24, 12

Page 34: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Just like with PHP, you can choose to organize your code

into objects and functions

@weaverryanThursday, May 24, 12

Page 35: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

var MagicBoxes = { initializeClick: function($container) { $container.find('.luigi') .click(this._handleLuigiClick); },

_handleLuigiClick: function(event) { event.preventDefault(); $luigi.addClass('active'); }};jQuery(document).ready(function() { var $wrap = $('.mario-world'); MagicBoxes.initializeClick($wrap);});

Thursday, May 24, 12

Page 36: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Princess Pro-tip

Be careful with objects, they can

increase readability, which threatens job

security

Thursday, May 24, 12

Page 37: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Objects: Advantages

‣ All of the logic of this “mini-app” is wrapped up inside a named object

‣ The jQuery document.ready is skinny: contains simple, descriptive calls to the object

‣ The object methods are reusable

Thursday, May 24, 12

Page 38: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

// hola! I’m just a local variablevar MagicBoxes = { // ...};

// I’m a global variable, available anywherewindow.MagicBoxes = {

};

Object Scope

Thursday, May 24, 12

Page 39: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

window.foo = 'foo-window';console.log(foo);// prints "foo-window"

bar = 'bar-global';console.log(window.bar);// prints "bar-global"

the “window”

Thursday, May 24, 12

Page 40: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Bad JavaScript moral #2:

Using global objects risks organizing your code into

separate, distinct units

@weaverryanThursday, May 24, 12

Page 41: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Mario’s bad JavaScript tip #3:

JavaScript’s “prototype” object model is too scary to use

@weaverryan

http://bit.ly/php-js-demo03 - Intro to the JS Prototype

Thursday, May 24, 12

Page 42: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Everything is an object

Thursday, May 24, 12

Page 43: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

var object1 = { fooProperty: 'foo!'}

console.log(object1.fooProperty);// prints “foo!”

An object with a property

Thursday, May 24, 12

Page 44: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

var alsoAnObject = function() { return 'foo-return!'};alsoAnObject.barProperty = 'bar!';

console.log(alsoAnObject.barProperty);// prints “bar!”

console.log(alsoAnObject());// prints “foo-return!”

Also an object with a property

Thursday, May 24, 12

Page 45: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

In PHP, we can create a class and then instantiate many

instances

@weaverryanThursday, May 24, 12

Page 46: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

<?php

class MagicBoxes{ public function __construct($option) { // ... }}

$magicBoxes1 = new MagicBoxes('foo');

$magicBoxes2 = new MagicBoxes('bar');Thursday, May 24, 12

Page 47: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

How can we do this in JavaScript?

@weaverryanThursday, May 24, 12

Page 48: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Imagine if we could do this craziness in PHP

@weaverryanThursday, May 24, 12

Page 49: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

$magicBox = function($var) { $this->var = $var;

$this->initialize();};$magicBox->prototype->initialize = function() { var_dump($this->var);};

$magicBoxObj = new $magicBox('something');// causes "something" to be printed

ImaginationLand PHP code

Thursday, May 24, 12

Page 50: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Yep, that’s how it works in JavaScript!

@weaverryanThursday, May 24, 12

Page 51: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

#1: Create a function

window.MagicBoxes = function($container) { this.$el = $container; this.initialize();};

Thursday, May 24, 12

Page 52: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

#2: Add things to your future object

MagicBoxes.prototype.initialize = function() { var $luigi = this.$el.find('.luigi'); $luigi.click(function(event) { event.preventDefault();

$(this).toggleClass('active'); });};

Thursday, May 24, 12

Page 53: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

#2: Add things to your future object

MagicBoxes.prototype.initialize = function()

The “prototype” is a magic place where you stick “future” things that will become a

part of the eventual new object

Thursday, May 24, 12

Page 54: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

#3: Instantiate your new object

jQuery(document).ready(function() { var $mario = $('.mario-world'); var magicBoxApp = new MagicBoxes($mario);});

Thursday, May 24, 12

Page 55: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

#4: Beers!

@weaverryanThursday, May 24, 12

Page 56: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Princess Pro-tip

Your speaker is a liar and a thief.

Using the prototype is for sissies!

Thursday, May 24, 12

Page 57: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Bowser rebuttal

Don’t listen to her!A gentleman and scholar named Garrison Locke is going to teach us the prototypical object model of JavaScript

tomorrow at 11:30 AM

Thursday, May 24, 12

Page 58: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Peach come-back

No you didn’t! Mario and I both agree that using objects in JavaScript is all weird! Viva the 1500 line jQuery

document.ready!

Thursday, May 24, 12

Page 59: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Bowser final word

Seriously, this is why I fight against you guys

Thursday, May 24, 12

Page 60: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Bowser final word

Your ignorance may seem blissful, but you work as a

detriment towards the larger cause of evolving

and learning asa community

Thursday, May 24, 12

Page 61: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Bowser final word

Thank God Garrison Locke will be teaching us Object-

oriented JavaScript tomorrow at 11:30 AM.

Thursday, May 24, 12

Page 62: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Bowser final word

He’s a much better speaker than this guy

Thursday, May 24, 12

Page 63: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Ryan does damage control on his presentation

Dude, I’m right here

Thursday, May 24, 12

Page 64: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Purple is a manly color

You really like that shirt...

Thursday, May 24, 12

Page 65: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Bad JavaScript moral #3:

Don’t use jQuery’s prototype or go to Garrison Locke’s

presentation tomorrow if you want unreadable JavaScript

@weaverryanThursday, May 24, 12

Page 66: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Mario’s bad JavaScript tip #4:

“this” probably always means “this”... don’t ask questions

@weaverryan

http://bit.ly/php-js-demo04 - Scoping Concerns

Thursday, May 24, 12

Page 67: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

$magicBox = new MagicBoxes('foo');$foo = new Foo();

// imaginary PHP function// this calls $magicBox->doSomething()// BUT, forces $this to actual be $foo inside// that object. Madness!call_func($magicBox, 'doSomething', $foo);

ImaginationLand PHP code

Thursday, May 24, 12

Page 68: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

With JavaScript objects, “this” may not always be what you

think it is

@weaverryanThursday, May 24, 12

Page 69: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

window.Boxes = function($container) { this.$el = $container;

var $luigi = this.$el.find('.luigi'); $luigi.on('click', this._luigiClick);};

Boxes.prototype._luigiClick = function(event) { event.preventDefault(); this.luigiFights($(this));};

Boxes.prototype.luigiFights = function($luigi) { $luigi.toggleClass('active');};

Thursday, May 24, 12

Page 70: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Boxes.prototype._luigiClick = function(event) { event.preventDefault(); this.luigiFights($(this));};

Is it our Boxes object?

Or is it the DOM element that triggered the jQuery event?

Thursday, May 24, 12

Page 71: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Boxes.prototype._luigiClick = function(event) { event.preventDefault(); this.luigiFights($(this));};

“this” is actually the DOM element that triggered the jQuery event

so “this” will not work pun intended...

Thursday, May 24, 12

Page 72: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

window.Boxes = function($container) { this.$el = $container;

var $luigi = this.$el.find('.luigi'); $luigi.on( 'click', $.proxy(this._luigiClick, this) );};

Boxes.prototype._luigiClick = function(event) { event.preventDefault(); this.makeLuigiFight($(event.currentTarget));};

Thursday, May 24, 12

Page 73: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

window.Boxes = function($container) { this.$el = $container;

var $luigi = this.$el.find('.luigi'); $luigi.on( 'click', $.proxy(this._luigiClick, this) );};

$.proxy forces _luigiClick to have “this” as this

object when called

Thursday, May 24, 12

Page 74: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Boxes.prototype._luigiClick = function(event) { event.preventDefault(); this.makeLuigiFight($(event.currentTarget));};

event.currentTarget returns the element that was

registered on this event (formerly “this”)

Thursday, May 24, 12

Page 75: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Mario’s bad JavaScript tip #5:

Avoid jQuery.extend so that you can repeat yourself as much as

possible: DRY*

@weaverryan

* definitely repeat yourselfhttp://bit.ly/php-js-demo

05 - jQuery extendsThursday, May 24, 12

Page 76: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

PHP ImaginationLand// foo has printFoo() method on it$foo = new Foo();

// bar has a printBar() method on it$bar = new Bar();

// now $fooBar has both methods!$fooBar = extend($foo, $bar);$fooBar->printFoo();$fooBar->printBar();

Thursday, May 24, 12

Page 77: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

var foo = { foo: function() { return 'foo-string'; }};var bar = { bar: function() { return 'bar-string'; }};

var fooBar = $.extend(foo, bar);console.log(fooBar.foo(), fooBar.bar());

Thursday, May 24, 12

Page 78: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Writing bad JavaScript tip #6:

Avoid using “delegate” events, and instead constantly worry

about re-attaching events to new elements

@weaverryan

http://bit.ly/php-js-demo06 - Delegate events

Thursday, May 24, 12

Page 79: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

this.$el.on( 'click', '.luigi', $.proxy(this._luigiClick, this));

this.$el.find('.luigi').on( 'click', $.proxy(this._luigiClick, this));

Can you see the difference?

Thursday, May 24, 12

Page 80: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

this.$el.find('.luigi')on( 'click', $.proxy(this._luigiClick, this));

Since the event is registered specifically on

“.luigi”, if any new “.luigi” elements are added, they will not

response to this event

Thursday, May 24, 12

Page 81: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

this.$el.on( 'click', '.luigi', $.proxy(this._luigiClick, this));

The event is registered on the wrapper, but looks for “.luigi”. If new “.luigi” elements are added to the

wrapper, they will automatically trigger the

event

Thursday, May 24, 12

Page 82: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

jQuery.live?

$('.foo').live('click', ...);

really just means this

$('body').on('click', '.foo', ...);

Thursday, May 24, 12

Page 83: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Mario’s bad JavaScript tip #7:

Self-executing JavaScript blocks are just plain scary looking

@weaverryan

http://bit.ly/php-js-demo07 - Self-executing blocks

Thursday, May 24, 12

Page 84: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

PHP Imaginationland

$dbConn = ''; // initialize this

$ourPreparedObject = (function($db) { $a = 5; $b = 10; $db->execute('...');

// ... a lot more complex stuff

return $someObject;})($dbConn);

$ourPreparedObject->callSomething();Thursday, May 24, 12

Page 85: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

window.MagicBoxes = (function($) {

return { // do a bunch of craziness };})(jQuery);

MagicBoxes.someMethod();

JavaScript Real Life

Thursday, May 24, 12

Page 86: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

window.MagicBoxes = (function($) {

return { // do a bunch of craziness };})(jQuery);

MagicBoxes.someMethod();

This is just a function...

Thursday, May 24, 12

Page 87: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

window.MagicBoxes = (function($) {

return { // do a bunch of craziness };})(jQuery);

MagicBoxes.someMethod();

Then we execute it, and pass in an argument

Thursday, May 24, 12

Page 88: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

window.MagicBoxes = (function($) {

return { // do a bunch of craziness };})(jQuery);

MagicBoxes.someMethod();

The function does any craziness it wants, but returns something

Thursday, May 24, 12

Page 89: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

window.MagicBoxes = (function($) {

return { // do a bunch of craziness };})(jQuery);

MagicBoxes.someMethod();

which we assign to a variable and then use

Thursday, May 24, 12

Page 90: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

And that’s it!

‣ Makes isolated chunks of code

‣ Used by most JavaScript libraries to isolate their code from yours

Thursday, May 24, 12

Page 91: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Backbone.js!

@weaverryanThursday, May 24, 12

Page 92: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Mario’s bad JavaScript tip #8:

Don’t use, or over-use Backbone.js

@weaverryan

http://bit.ly/php-js-demo08 - A Backbone View

Thursday, May 24, 12

Page 93: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

@weaverryan

‣ Set of tools for creating heavy front-end applications:

* views* models* router

What is Backbone?

Thursday, May 24, 12

Page 94: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Views

A formalized method for creating a JavaScript object that “manages” a

DOM element

Thursday, May 24, 12

Page 95: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Views

We’ve been building an object that’s very similar to a Backbone view

Thursday, May 24, 12

Page 96: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

var MagicBoxes = Backbone.View.extend({ events: { 'click .luigi': '_luigiClick' },

initialize: function() { _.bindAll(this, '_luigiClick') },

_luigiClick: function(event) { event.preventDefault(); $(event.currentTarget) .toggleClass('active'); }});var magicBoxApp = new MagicBoxes({ el: $('.mario-world')});

Thursday, May 24, 12

Page 97: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

var MagicBoxes = Backbone.View.extend({ events: { 'click .luigi': '_luigiClick' },

initialize: function() { _.bindAll(this, '_luigiClick') },

_luigiClick: function(event) { event.preventDefault(); $(event.currentTarget) .toggleClass('active'); }});var magicBoxApp = new MagicBoxes({ el: $('.mario-world')});

That sure is a simple way to bind to events. And thanks to “delegate” events, when the

DOM updates, the events still fire on new elements!

Thursday, May 24, 12

Page 98: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

var MagicBoxes = Backbone.View.extend({ events: { 'click .luigi': '_luigiClick' },

initialize: function() { _.bindAll(this, '_luigiClick') },

_luigiClick: function(event) { event.preventDefault(); $(event.currentTarget) .toggleClass('active'); }});var magicBoxApp = new MagicBoxes({ el: $('.mario-world')});

initialize() is automatically called by Backbone.

Thursday, May 24, 12

Page 99: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

var MagicBoxes = Backbone.View.extend({ events: { 'click .luigi': '_luigiClick' },

initialize: function() { _.bindAll(this, '_luigiClick') },

_luigiClick: function(event) { event.preventDefault(); $(event.currentTarget) .toggleClass('active'); }});var magicBoxApp = new MagicBoxes({ el: $('.mario-world')});

_.bindAll is from underscore.js - it does the same job as jQuery.proxy: guarantees that “this” is

this object in that function

Thursday, May 24, 12

Page 100: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

var MagicBoxes = Backbone.View.extend({ events: { 'click .luigi': '_luigiClick' },

initialize: function() { _.bindAll(this, '_luigiClick') },

_luigiClick: function(event) { event.preventDefault(); $(event.currentTarget) .toggleClass('active'); }});var magicBoxApp = new MagicBoxes({ el: $('.mario-world')});

We attach a real DOM element to the view by

passing it into a pre-made constructor as “el”. In the object, it’s available via

this.el

Thursday, May 24, 12

Page 101: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Models

A formalized object that just holds key-value data on it

Thursday, May 24, 12

Page 102: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

var Character = Backbone.Model.extend();

var mario = new Character({ 'name': 'Mario'});var peach = new Character({ 'name': 'Peach', 'status': 'captured'});

// change some datapeach.set({ 'status': 'rescued'});

Thursday, May 24, 12

Page 103: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

peach.on('change', function(changedModel) { var name = changedModel.get('name'); console.log(name + ' was updated!');});

// will cause "Peach was updated" to logpeach.set({ 'status': 'rescued'});

Events make them wonderful

Thursday, May 24, 12

Page 104: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

var Character = Backbone.Model.extend();var App = Backbone.View.extend({ initialize: function() { _.bindAll(this, '_updateName'); this.model.on('change', this._updateName); this._updateName(); },

_updateName: function() { var name = this.model.get('name'); this.$('.name').html(name); }});

var mario = new Character({ 'name': 'Mario'});

var app = new App({ el: $('.mario-world'), model: mario});

Thursday, May 24, 12

Page 105: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

var Character = Backbone.Model.extend();var App = Backbone.View.extend({ initialize: function() { _.bindAll(this, '_updateName'); this.model.on('change', this._updateName); this._updateName(); },

_updateName: function() { var name = this.model.get('name'); this.$('.name').html(name); }});

When the model changes, we can update the DOM anywhere that we’re listening for

that change

Thursday, May 24, 12

Page 106: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Backbone is a great solution

Thursday, May 24, 12

Page 107: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

But do you have a problem?

Thursday, May 24, 12

Page 108: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

@weaverryan

‣ Easy event binding

‣ An object-oriented structure that’s setup for you already

‣ “Patterns” to follow as you get comfortable

Views: Easy win

Thursday, May 24, 12

Page 109: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

@weaverryan

‣ There are 2 types of Views:

1) Views applied to existing elements in the DOM (like our example)

2) Views that are given an empty element, and then render using client-side templates and model data

Views: Who Renders?

Easy Win

Depends

Thursday, May 24, 12

Page 110: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

@weaverryan

‣ A highly interactive app that communicates to a PHP API that is never responsible for rendering any HTML

When to use Models + Views

Thursday, May 24, 12

Page 111: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

@weaverryan

‣ An app where PHP renders HTML

‣ An app where the API isn’t robust

When *not* to use Models + Views

Thursday, May 24, 12

Page 112: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

@weaverryan

‣ If your PHP application renders HTML and you also try to use Backbone Views that render HTML, you’ll need duplicate templates

‣ Do one or the other

Duplication

Thursday, May 24, 12

Page 113: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

@weaverryan

You can potentially duplicate a lot of work both on the client and server sides:

‣ validation‣ models‣ templates

Duplication

Thursday, May 24, 12

Page 114: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

@weaverryan

‣ Not really comfortable with a fully-client side application? Use Backbone views attached to existing DOM element

‣ Feel pretty awesome about doing everything in the browser? Dive in :)

Find your Comfort Zone

Thursday, May 24, 12

Page 115: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

Thanks...

Ryan Weaver@weaverryan

Thursday, May 24, 12

Page 116: JavaScript Best Practices, Backbone.js, and Mario for the PHP Develop

... and we love you!

Ryan Weaver@weaverryan

Ryan Weaver@weaverryan

http://joind.in/talk/view/6508

Thursday, May 24, 12