0
JAVASCRIPT BEST                  PRACTICES & BACKBONE.JS                   FOR THE PHP DEVELOPER                         R...
7 tips for writing JavaScript                                 like a jerk                                      +          ...
Who is this dude?               • Co-author of the Symfony2 Docs               • KnpLabs US - Symfony               consul...
Chapter 1: Java$criptQuery            Look mom, I’m a JavaScript professional     @weaverryanThursday, May 24, 12
1. jQuery(document).ready(...)          2. 1500 lines, with deeply          nested anonymous functions          3. Profit!...
Too soon?                       ... sry fb, luv u kthxbye     @weaverryanThursday, May 24, 12
The brains behind this                          presentation...Thursday, May 24, 12
source:                  http://www.geeky-gadgets.com/super-mario-bros-matryoshka-dolls/Thursday, May 24, 12
Thursday, May 24, 12
<div class="mario box">    .mario    <div class="luigi box">        .luigi        <div class="kick-butt">...</div>        ...
Let’s kick some arse! jQuery(document).ready(function() {     var $luigi = $(.event-details .luigi);               $luigi....
DEMO!!!!!                       http://bit.ly/php-js-demo                         0 - The starting pointThursday, May 24, 12
Princess Pro-tip                        Instead of listening                       to this guy drone on,                  ...
‣ Click either .luigi or .peach      ‣ the .luigi wrapper gets the active classThursday, May 24, 12
Mario’s bad JavaScript tip #1:       Ignore the jQuery “event” object,             it’s probably stupid...   http://bit.ly...
Events happenThursday, May 24, 12
Event      Click!           1) You click!                       2) An event travels up the treeThursday, May 24, 12
Browser event                           versus                        jQuery event             ‣ The browser event contain...
$luigi.click(function(event) {        // ...    });        ‣ event.target: The actual element that        received the cli...
$luigi.click(function(event) {        // ...    });                       Our listener is registered                      ...
If you click .peach:        event.target:        .peach        event.currentTarget: .luigiThursday, May 24, 12
If you click .luigi:        event.target:        .luigi        event.currentTarget: .luigiThursday, May 24, 12
event.currentTarget                                       ==                                      this                  * ...
$luigi.click(function(event) {        // these are the same!        $(event.currentTarget)            .addClass(active);  ...
Preventing the damn                             “#” on the URL   $luigi.click(function() {       $(this).addClass(active);...
Princess Pro-tip              return false stops             propagation, and is a              great way to screw        ...
... but if you like your                              coworkers...   $luigi.click(function(event) {       event.preventDef...
Bad JavaScript moral #1:                        jQuery’s event object is a                       dangerous source of usefu...
Mario bad JavaScript tip #2:           Avoid using objects: they       threaten to organize your code...               and...
A PHP object   @weaverryanThursday, May 24, 12
<?php  class MagicBoxes  {      public function initializeClick($wrapper)      {          // ...      }  }  $magicBoxes = ...
A JavaScript object   @weaverryanThursday, May 24, 12
var MagicBoxes = {     someProperty: 0,                initializeClick: function($container) {                    // ...  ...
Just like with PHP, you can              choose to organize your code                into objects and functions   @weaverr...
var MagicBoxes = {       initializeClick: function($container) {           $container.find(.luigi)               .click(th...
Princess Pro-tip                Be careful with               objects, they can             increase readability,         ...
Objects: Advantages        ‣ All of the logic of this “mini-app” is        wrapped up inside a named object        ‣ The j...
Object Scope     // hola! I’m just a local variable     var MagicBoxes = {         // ...     };     // I’m a global varia...
the “window”     window.foo = foo-window;     console.log(foo);     // prints "foo-window"     bar = bar-global;     conso...
Bad JavaScript moral #2:                       Using global objects risks                       organizing your code into ...
Mario’s bad JavaScript tip #3:            JavaScript’s “prototype” object              model is too scary to use   http://...
Everything is an objectThursday, May 24, 12
An object with a property        var object1 = {            fooProperty: foo!        }        console.log(object1.fooPrope...
Also an object with a property        var alsoAnObject = function() {            return foo-return!        };        alsoA...
In PHP, we can create a class                and then instantiate many                       instances   @weaverryanThursd...
<?php  class MagicBoxes  {      public function __construct($option)      {          // ...      }  }  $magicBoxes1 = new ...
How can we do this in                           JavaScript?   @weaverryanThursday, May 24, 12
Imagine if we could do this                           craziness in PHP   @weaverryanThursday, May 24, 12
ImaginationLand PHP code $magicBox = function($var) {     $this->var = $var;               $this->initialize(); }; $magicB...
Yep, that’s how it works in                              JavaScript!   @weaverryanThursday, May 24, 12
#1: Create a function   window.MagicBoxes = function($container) {       this.$el = $container;       this.initialize();  ...
#2: Add things to your future                                  object   MagicBoxes.prototype.initialize = function()   {  ...
#2: Add things to your future                                  object   MagicBoxes.prototype.initialize = function()      ...
#3: Instantiate your new object jQuery(document).ready(function() {     var $mario = $(.mario-world);     var magicBoxApp ...
#4: Beers!   @weaverryanThursday, May 24, 12
Princess Pro-tip                    Your speaker is a                    liar and a thief.                   Using the pro...
Bowser rebuttal                Don’t listen to her!            A gentleman and scholar named             Garrison Locke is...
Peach come-back               No you didn’t! Mario and I              both agree that using objects               in JavaS...
Bowser final word                  Seriously, this is why I                   fight against you guysThursday, May 24, 12
Bowser final word             Your ignorance may seem           blissful, but you work as a              detriment towards ...
Bowser final word            Thank God Garrison Locke           will be teaching us Object-               oriented JavaScri...
Bowser final word             He’s a much better speaker                    than this guyThursday, May 24, 12
Ryan does damage control                     on his presentation                       Dude, I’m right hereThursday, May 2...
Purple is a manly color                       You really like that                             shirt...Thursday, May 24, 12
Bad JavaScript moral #3:           Don’t use jQuery’s prototype or               go to Garrison Locke’s            present...
Mario’s bad JavaScript tip #4:               “this” probably always means                 “this”... don’t ask questions   ...
ImaginationLand PHP code $magicBox = new MagicBoxes(foo); $foo = new Foo(); // imaginary PHP function // this calls $magic...
With JavaScript objects, “this”              may not always be what you                       think it is   @weaverryanThu...
window.Boxes = function($container) {     this.$el = $container;              var $luigi = this.$el.find(.luigi);         ...
Is it our Boxes object? Boxes.prototype._luigiClick = function(event) {     event.preventDefault();     this.luigiFights($...
“this” is actually the DOM element                          that triggered the jQuery event Boxes.prototype._luigiClick = ...
window.Boxes = function($container) {     this.$el = $container;              var $luigi = this.$el.find(.luigi);         ...
window.Boxes = function($container) {     this.$el = $container;              var $luigi = this.$el.find(.luigi);         ...
event.currentTarget returns                           the element that was                         registered on this even...
Mario’s bad JavaScript tip #5:         Avoid jQuery.extend so that you         can repeat yourself as much as             ...
PHP ImaginationLand    // foo has printFoo() method on it    $foo = new Foo();    // bar has a printBar() method on it    ...
var foo = {      foo: function() {          return foo-string;      }  };  var bar = {      bar: function() {          ret...
Writing bad JavaScript tip #6:       Avoid using “delegate” events,        and instead constantly worry      about re-atta...
Can you see the difference?    this.$el.find(.luigi).on(        click,        $.proxy(this._luigiClick, this)    );   this...
this.$el.find(.luigi)on(        click,        $.proxy(this._luigiClick, this)    );                           Since the ev...
The event is registered on                       the wrapper, but looks for                       “.luigi”. If new “.luigi...
jQuery.live?                       $(.foo).live(click, ...);                             really just means this           ...
Mario’s bad JavaScript tip #7:       Self-executing JavaScript blocks         are just plain scary looking        http://b...
PHP Imaginationland             $dbConn = ; // initialize this             $ourPreparedObject = (function($db) {          ...
JavaScript Real Life         window.MagicBoxes = (function($) {             return {                 // do a bunch of craz...
This is just a function...         window.MagicBoxes = (function($) {             return {                 // do a bunch o...
Then we execute it, and pass in an argument         window.MagicBoxes = (function($) {             return {               ...
The function does any craziness it                         wants, but returns something         window.MagicBoxes = (funct...
which we assign to a variable and then use         window.MagicBoxes = (function($) {             return {                ...
And that’s it!        ‣ Makes isolated chunks of code        ‣ Used by most JavaScript libraries to        isolate their c...
Backbone.js!   @weaverryanThursday, May 24, 12
Mario’s bad JavaScript tip #8:                       Don’t use, or over-use                           Backbone.js         ...
What is Backbone?          ‣ Set of tools for creating heavy front-          end applications:            * views         ...
Views                  A formalized method for creating a                  JavaScript object that “manages” a             ...
Views                We’ve been building an object that’s                 very similar to a Backbone viewThursday, May 24,...
var MagicBoxes = Backbone.View.extend({         events: {             click .luigi: _luigiClick         },                ...
var MagicBoxes = Backbone.View.extend({         events: {             click .luigi: _luigiClick         },                ...
var MagicBoxes = Backbone.View.extend({         events: {             click .luigi: _luigiClick         },                ...
var MagicBoxes = Backbone.View.extend({         events: {             click .luigi: _luigiClick         },                ...
var MagicBoxes = Backbone.View.extend({         events: {             click .luigi: _luigiClick         },                ...
Models                       A formalized object that just holds                             key-value data on itThursday,...
var Character = Backbone.Model.extend();               var mario = new Character({                   name: Mario          ...
Events make them wonderful     peach.on(change, function(changedModel) {         var name = changedModel.get(name);       ...
var Character = Backbone.Model.extend();             var App = Backbone.View.extend({                 initialize: function...
var Character = Backbone.Model.extend();             var App = Backbone.View.extend({                 initialize: function...
Backbone is a great solutionThursday, May 24, 12
But do you have a problem?Thursday, May 24, 12
Views: Easy win          ‣ Easy event binding          ‣ An object-oriented structure that’s          setup for you alread...
Views: Who Renders?        ‣ There are 2 types of Views:     Easy              1) Views applied to existing elements     W...
When to use Models + Views            ‣ A highly interactive app that            communicates to a PHP API that is        ...
When *not* to use Models + Views               ‣ An app where PHP renders HTML               ‣ An app where the API isn’t ...
Duplication               ‣ If your PHP application renders               HTML and you also try to use               Backb...
Duplication               You can potentially duplicate a lot of               work both on the client and server         ...
Find your Comfort Zone               ‣ Not really comfortable with a fully-               client side application? Use    ...
Thanks...                       Ryan Weaver                       @weaverryanThursday, May 24, 12
... and we love you!                         http://joind.in/talk/view/6508                              Ryan Weaver      ...
Upcoming SlideShare
Loading in...5
×

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

15,193

Published on

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

Published in: Technology
2 Comments
25 Likes
Statistics
Notes
No Downloads
Views
Total Views
15,193
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
128
Comments
2
Likes
25
Embeds 0
No embeds

No notes for slide

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

  1. 1. JAVASCRIPT BEST PRACTICES & BACKBONE.JS FOR THE PHP DEVELOPER Ryan Weaver @weaverryanThursday, May 24, 12
  2. 2. 7 tips for writing JavaScript like a jerk + What to take and leave in Backbone.jsThursday, May 24, 12
  3. 3. Who is this dude? • Co-author of the Symfony2 Docs • KnpLabs US - Symfony consulting, training, Kumbaya • Writer for KnpUniversity.com screencasts • Fiancee of the much more talented @leannapelham -----> June 9th, 2012! http://www.knplabs.com/en @weaverryan http://www.github.com/weaverryanThursday, May 24, 12
  4. 4. Chapter 1: Java$criptQuery Look mom, I’m a JavaScript professional @weaverryanThursday, May 24, 12
  5. 5. 1. jQuery(document).ready(...) 2. 1500 lines, with deeply nested anonymous functions 3. Profit! $$$ @weaverryanThursday, May 24, 12
  6. 6. Too soon? ... sry fb, luv u kthxbye @weaverryanThursday, May 24, 12
  7. 7. The brains behind this presentation...Thursday, May 24, 12
  8. 8. source: http://www.geeky-gadgets.com/super-mario-bros-matryoshka-dolls/Thursday, May 24, 12
  9. 9. Thursday, May 24, 12
  10. 10. <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
  11. 11. Let’s kick some arse! jQuery(document).ready(function() { var $luigi = $(.event-details .luigi); $luigi.click(function() { $(this).addClass(active); return false; }); });Thursday, May 24, 12
  12. 12. DEMO!!!!! http://bit.ly/php-js-demo 0 - The starting pointThursday, May 24, 12
  13. 13. 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-playThursday, May 24, 12
  14. 14. ‣ Click either .luigi or .peach ‣ the .luigi wrapper gets the active classThursday, May 24, 12
  15. 15. Mario’s bad JavaScript tip #1: Ignore the jQuery “event” object, it’s probably stupid... http://bit.ly/php-js-demo 01 - The jQuery Event @weaverryanThursday, May 24, 12
  16. 16. Events happenThursday, May 24, 12
  17. 17. Event Click! 1) You click! 2) An event travels up the treeThursday, May 24, 12
  18. 18. Browser event versus jQuery event ‣ The browser event contains all the information about what happened ‣the jQuery event cleans up cross- browser compatibility uglinessThursday, May 24, 12
  19. 19. $luigi.click(function(event) { // ... }); ‣ event.target: The actual element that received the click ‣ event.currentTarget: The element that this listener was attached toThursday, May 24, 12
  20. 20. $luigi.click(function(event) { // ... }); Our listener is registered on .luigiThursday, May 24, 12
  21. 21. If you click .peach: event.target: .peach event.currentTarget: .luigiThursday, May 24, 12
  22. 22. If you click .luigi: event.target: .luigi event.currentTarget: .luigiThursday, May 24, 12
  23. 23. event.currentTarget == this * unless you screw with scope, which we’ll see!Thursday, May 24, 12
  24. 24. $luigi.click(function(event) { // these are the same! $(event.currentTarget) .addClass(active); $luigi.addClass(active); });Thursday, May 24, 12
  25. 25. Preventing the damn “#” on the URL $luigi.click(function() { $(this).addClass(active); return false; });Thursday, May 24, 12
  26. 26. 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
  27. 27. ... but if you like your coworkers... $luigi.click(function(event) { event.preventDefault(); // ... }); The event keeps traveling up the DOMThursday, May 24, 12
  28. 28. Bad JavaScript moral #1: jQuery’s event object is a dangerous source of useful information and control @weaverryanThursday, May 24, 12
  29. 29. Mario bad JavaScript tip #2: Avoid using objects: they threaten to organize your code... and are creepy... http://bit.ly/php-js-demo 02 - Basic jQuery Objects @weaverryanThursday, May 24, 12
  30. 30. A PHP object @weaverryanThursday, May 24, 12
  31. 31. <?php class MagicBoxes { public function initializeClick($wrapper) { // ... } } $magicBoxes = new MagicBoxes(); $magicBoxes->initializeClick(something);Thursday, May 24, 12
  32. 32. A JavaScript object @weaverryanThursday, May 24, 12
  33. 33. var MagicBoxes = { someProperty: 0, initializeClick: function($container) { // ... } }; MagicBoxes.initializeClick(something);Thursday, May 24, 12
  34. 34. Just like with PHP, you can choose to organize your code into objects and functions @weaverryanThursday, May 24, 12
  35. 35. 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
  36. 36. Princess Pro-tip Be careful with objects, they can increase readability, which threatens job securityThursday, May 24, 12
  37. 37. 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 reusableThursday, May 24, 12
  38. 38. Object Scope // hola! I’m just a local variable var MagicBoxes = { // ... }; // I’m a global variable, available anywhere window.MagicBoxes = { };Thursday, May 24, 12
  39. 39. the “window” window.foo = foo-window; console.log(foo); // prints "foo-window" bar = bar-global; console.log(window.bar); // prints "bar-global"Thursday, May 24, 12
  40. 40. Bad JavaScript moral #2: Using global objects risks organizing your code into separate, distinct units @weaverryanThursday, May 24, 12
  41. 41. Mario’s bad JavaScript tip #3: JavaScript’s “prototype” object model is too scary to use http://bit.ly/php-js-demo 03 - Intro to the JS Prototype @weaverryanThursday, May 24, 12
  42. 42. Everything is an objectThursday, May 24, 12
  43. 43. An object with a property var object1 = { fooProperty: foo! } console.log(object1.fooProperty); // prints “foo!”Thursday, May 24, 12
  44. 44. Also an object with a property var alsoAnObject = function() { return foo-return! }; alsoAnObject.barProperty = bar!; console.log(alsoAnObject.barProperty); // prints “bar!” console.log(alsoAnObject()); // prints “foo-return!”Thursday, May 24, 12
  45. 45. In PHP, we can create a class and then instantiate many instances @weaverryanThursday, May 24, 12
  46. 46. <?php class MagicBoxes { public function __construct($option) { // ... } } $magicBoxes1 = new MagicBoxes(foo); $magicBoxes2 = new MagicBoxes(bar);Thursday, May 24, 12
  47. 47. How can we do this in JavaScript? @weaverryanThursday, May 24, 12
  48. 48. Imagine if we could do this craziness in PHP @weaverryanThursday, May 24, 12
  49. 49. ImaginationLand PHP code $magicBox = function($var) { $this->var = $var; $this->initialize(); }; $magicBox->prototype->initialize = function() { var_dump($this->var); }; $magicBoxObj = new $magicBox(something); // causes "something" to be printedThursday, May 24, 12
  50. 50. Yep, that’s how it works in JavaScript! @weaverryanThursday, May 24, 12
  51. 51. #1: Create a function window.MagicBoxes = function($container) { this.$el = $container; this.initialize(); };Thursday, May 24, 12
  52. 52. #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
  53. 53. #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 objectThursday, May 24, 12
  54. 54. #3: Instantiate your new object jQuery(document).ready(function() { var $mario = $(.mario-world); var magicBoxApp = new MagicBoxes($mario); });Thursday, May 24, 12
  55. 55. #4: Beers! @weaverryanThursday, May 24, 12
  56. 56. Princess Pro-tip Your speaker is a liar and a thief. Using the prototype is for sissies!Thursday, May 24, 12
  57. 57. 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 AMThursday, May 24, 12
  58. 58. 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
  59. 59. Bowser final word Seriously, this is why I fight against you guysThursday, May 24, 12
  60. 60. Bowser final word Your ignorance may seem blissful, but you work as a detriment towards the larger cause of evolving and learning as a communityThursday, May 24, 12
  61. 61. Bowser final word Thank God Garrison Locke will be teaching us Object- oriented JavaScript tomorrow at 11:30 AM.Thursday, May 24, 12
  62. 62. Bowser final word He’s a much better speaker than this guyThursday, May 24, 12
  63. 63. Ryan does damage control on his presentation Dude, I’m right hereThursday, May 24, 12
  64. 64. Purple is a manly color You really like that shirt...Thursday, May 24, 12
  65. 65. 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
  66. 66. Mario’s bad JavaScript tip #4: “this” probably always means “this”... don’t ask questions http://bit.ly/php-js-demo 04 - Scoping Concerns @weaverryanThursday, May 24, 12
  67. 67. ImaginationLand PHP code $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);Thursday, May 24, 12
  68. 68. With JavaScript objects, “this” may not always be what you think it is @weaverryanThursday, May 24, 12
  69. 69. 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
  70. 70. Is it our Boxes object? Boxes.prototype._luigiClick = function(event) { event.preventDefault(); this.luigiFights($(this)); }; Or is it the DOM element that triggered the jQuery event?Thursday, May 24, 12
  71. 71. “this” is actually the DOM element that triggered the jQuery event Boxes.prototype._luigiClick = function(event) { event.preventDefault(); this.luigiFights($(this)); }; so “this” will not work pun intended...Thursday, May 24, 12
  72. 72. 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
  73. 73. 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 calledThursday, May 24, 12
  74. 74. event.currentTarget returns the element that was registered on this event (formerly “this”) Boxes.prototype._luigiClick = function(event) { event.preventDefault(); this.makeLuigiFight($(event.currentTarget)); };Thursday, May 24, 12
  75. 75. Mario’s bad JavaScript tip #5: Avoid jQuery.extend so that you can repeat yourself as much as possible: DRY* * definitely repeat yourself http://bit.ly/php-js-demo @weaverryan 05 - jQuery extendsThursday, May 24, 12
  76. 76. 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
  77. 77. 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
  78. 78. Writing bad JavaScript tip #6: Avoid using “delegate” events, and instead constantly worry about re-attaching events to new elements http://bit.ly/php-js-demo 06 - Delegate events @weaverryanThursday, May 24, 12
  79. 79. Can you see the difference? this.$el.find(.luigi).on( click, $.proxy(this._luigiClick, this) ); this.$el.on( click, .luigi, $.proxy(this._luigiClick, this) );Thursday, May 24, 12
  80. 80. 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 eventThursday, May 24, 12
  81. 81. 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 this.$el.on( click, .luigi, $.proxy(this._luigiClick, this) );Thursday, May 24, 12
  82. 82. jQuery.live? $(.foo).live(click, ...); really just means this $(body).on(click, .foo, ...);Thursday, May 24, 12
  83. 83. Mario’s bad JavaScript tip #7: Self-executing JavaScript blocks are just plain scary looking http://bit.ly/php-js-demo 07 - Self-executing blocks @weaverryanThursday, May 24, 12
  84. 84. 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
  85. 85. JavaScript Real Life window.MagicBoxes = (function($) { return { // do a bunch of craziness }; })(jQuery); MagicBoxes.someMethod();Thursday, May 24, 12
  86. 86. This is just a function... window.MagicBoxes = (function($) { return { // do a bunch of craziness }; })(jQuery); MagicBoxes.someMethod();Thursday, May 24, 12
  87. 87. Then we execute it, and pass in an argument window.MagicBoxes = (function($) { return { // do a bunch of craziness }; })(jQuery); MagicBoxes.someMethod();Thursday, May 24, 12
  88. 88. The function does any craziness it wants, but returns something window.MagicBoxes = (function($) { return { // do a bunch of craziness }; })(jQuery); MagicBoxes.someMethod();Thursday, May 24, 12
  89. 89. which we assign to a variable and then use window.MagicBoxes = (function($) { return { // do a bunch of craziness }; })(jQuery); MagicBoxes.someMethod();Thursday, May 24, 12
  90. 90. And that’s it! ‣ Makes isolated chunks of code ‣ Used by most JavaScript libraries to isolate their code from yoursThursday, May 24, 12
  91. 91. Backbone.js! @weaverryanThursday, May 24, 12
  92. 92. Mario’s bad JavaScript tip #8: Don’t use, or over-use Backbone.js http://bit.ly/php-js-demo 08 - A Backbone View @weaverryanThursday, May 24, 12
  93. 93. What is Backbone? ‣ Set of tools for creating heavy front- end applications: * views * models * router @weaverryanThursday, May 24, 12
  94. 94. Views A formalized method for creating a JavaScript object that “manages” a DOM elementThursday, May 24, 12
  95. 95. Views We’ve been building an object that’s very similar to a Backbone viewThursday, May 24, 12
  96. 96. 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
  97. 97. var MagicBoxes = Backbone.View.extend({ events: { click .luigi: _luigiClick }, initialize: function() { _.bindAll(this, _luigiClick) }, That sure is a simple way to bind to events. And thanks to _luigiClick: function(event) { “delegate” events, when the event.preventDefault(); DOM updates, the events still $(event.currentTarget) fire on new elements! .toggleClass(active); } }); var magicBoxApp = new MagicBoxes({ el: $(.mario-world) });Thursday, May 24, 12
  98. 98. var MagicBoxes = Backbone.View.extend({ events: { click .luigi: _luigiClick }, initialize: function() { _.bindAll(this, _luigiClick) }, _luigiClick: function(event) { event.preventDefault(); $(event.currentTarget) automatically initialize() is .toggleClass(active); called by Backbone. } }); var magicBoxApp = new MagicBoxes({ el: $(.mario-world) });Thursday, May 24, 12
  99. 99. var MagicBoxes = Backbone.View.extend({ events: { click .luigi: _luigiClick }, initialize: function() { _.bindAll(this, _luigiClick) }, _luigiClick: function(event) { _.bindAll is from event.preventDefault(); underscore.js - it does the $(event.currentTarget) same job as jQuery.proxy: .toggleClass(active); } guarantees that “this” is }); this object in that function var magicBoxApp = new MagicBoxes({ el: $(.mario-world) });Thursday, May 24, 12
  100. 100. var MagicBoxes = Backbone.View.extend({ events: { click .luigi: _luigiClick }, initialize: function() { _.bindAll(this, _luigiClick) DOM We attach a real }, element to the view by passing it into a pre-made _luigiClick: function(event) { constructor as “el”. In the event.preventDefault(); object, it’s available via $(event.currentTarget) this.el .toggleClass(active); } }); var magicBoxApp = new MagicBoxes({ el: $(.mario-world) });Thursday, May 24, 12
  101. 101. Models A formalized object that just holds key-value data on itThursday, May 24, 12
  102. 102. var Character = Backbone.Model.extend(); var mario = new Character({ name: Mario }); var peach = new Character({ name: Peach, status: captured }); // change some data peach.set({ status: rescued });Thursday, May 24, 12
  103. 103. Events make them wonderful peach.on(change, function(changedModel) { var name = changedModel.get(name); console.log(name + was updated!); }); // will cause "Peach was updated" to log peach.set({ status: rescued });Thursday, May 24, 12
  104. 104. 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
  105. 105. 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 changeThursday, May 24, 12
  106. 106. Backbone is a great solutionThursday, May 24, 12
  107. 107. But do you have a problem?Thursday, May 24, 12
  108. 108. Views: Easy win ‣ Easy event binding ‣ An object-oriented structure that’s setup for you already ‣ “Patterns” to follow as you get comfortable @weaverryanThursday, May 24, 12
  109. 109. Views: Who Renders? ‣ There are 2 types of Views: Easy 1) Views applied to existing elements Win in the DOM (like our example) 2) Views that are given an empty Depends element, and then render using client- side templates and model data @weaverryanThursday, May 24, 12
  110. 110. When to use Models + Views ‣ A highly interactive app that communicates to a PHP API that is never responsible for rendering any HTML @weaverryanThursday, May 24, 12
  111. 111. When *not* to use Models + Views ‣ An app where PHP renders HTML ‣ An app where the API isn’t robust @weaverryanThursday, May 24, 12
  112. 112. Duplication ‣ 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 @weaverryanThursday, May 24, 12
  113. 113. Duplication You can potentially duplicate a lot of work both on the client and server sides: ‣ validation ‣ models ‣ templates @weaverryanThursday, May 24, 12
  114. 114. Find your Comfort Zone ‣ 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 :) @weaverryanThursday, May 24, 12
  115. 115. Thanks... Ryan Weaver @weaverryanThursday, May 24, 12
  116. 116. ... and we love you! http://joind.in/talk/view/6508 Ryan Weaver @weaverryan Ryan Weaver @weaverryanThursday, May 24, 12
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×