SlideShare a Scribd company logo
JAVASCRIPT BEST
                  PRACTICES & BACKBONE.JS
                   FOR THE PHP DEVELOPER
                         Ryan Weaver
                         @weaverryan




Thursday, May 24, 12
7 tips for writing JavaScript
                                 like a jerk
                                      +
                        What to take and leave in
                                Backbone.js


Thursday, May 24, 12
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/weaverryan
Thursday, May 24, 12
Chapter 1: Java$criptQuery
            Look mom, I’m a JavaScript professional




     @weaverryan
Thursday, May 24, 12
1. jQuery(document).ready(...)
          2. 1500 lines, with deeply
          nested anonymous functions
          3. Profit! $$$


     @weaverryan
Thursday, May 24, 12
Too soon?
                       ... sry fb, luv u kthxbye
     @weaverryan
Thursday, 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>
        <a href="#" class="peach box">
             .peach
        </a>
    </div>
</div>


Thursday, May 24, 12
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
DEMO!!!!!


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


                         0 - The starting point




Thursday, May 24, 12
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
‣ Click either .luigi or .peach
      ‣ the .luigi wrapper gets the active class

Thursday, May 24, 12
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
   @weaverryan
Thursday, May 24, 12
Events happen




Thursday, May 24, 12
Event




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


Thursday, May 24, 12
Browser event
                           versus
                        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
$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
$luigi.click(function(event) {
        // ...
    });



                       Our listener is registered
                                on .luigi


Thursday, May 24, 12
If you click .peach:
        event.target:        .peach
        event.currentTarget: .luigi

Thursday, May 24, 12
If you click .luigi:
        event.target:        .luigi
        event.currentTarget: .luigi

Thursday, May 24, 12
event.currentTarget

                                       ==

                                      this

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



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



Thursday, May 24, 12
Preventing the damn
                             “#” on the URL

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

                       return false;
   });


Thursday, May 24, 12
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
... but if you like your
                              coworkers...
   $luigi.click(function(event) {
       event.preventDefault();

                       // ...
   });

             The event keeps traveling up
             the DOM
Thursday, May 24, 12
Bad JavaScript moral #1:


                        jQuery’s event object is a
                       dangerous source of useful
                         information and control



   @weaverryan
Thursday, May 24, 12
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
   @weaverryan
Thursday, May 24, 12
A PHP object




   @weaverryan
Thursday, May 24, 12
<?php

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

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


Thursday, May 24, 12
A JavaScript object




   @weaverryan
Thursday, May 24, 12
var MagicBoxes = {
     someProperty: 0,

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

 MagicBoxes.initializeClick(something);




Thursday, May 24, 12
Just like with PHP, you can
              choose to organize your code
                into objects and functions


   @weaverryan
Thursday, May 24, 12
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
Princess Pro-tip

                Be careful with
               objects, they can
             increase readability,
              which threatens job
                    security


Thursday, May 24, 12
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
Object Scope
     // hola! I’m just a local variable
     var MagicBoxes = {
         // ...
     };

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

     };



Thursday, May 24, 12
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
Bad JavaScript moral #2:


                       Using global objects risks
                       organizing your code into
                        separate, distinct units



   @weaverryan
Thursday, May 24, 12
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
   @weaverryan
Thursday, May 24, 12
Everything is an object




Thursday, May 24, 12
An object with a property
        var object1 = {
            fooProperty: 'foo!'
        }

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




Thursday, May 24, 12
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
In PHP, we can create a class
                and then instantiate many
                       instances


   @weaverryan
Thursday, May 24, 12
<?php

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

  $magicBoxes1 = new MagicBoxes('foo');

  $magicBoxes2 = new MagicBoxes('bar');
Thursday, May 24, 12
How can we do this in
                           JavaScript?



   @weaverryan
Thursday, May 24, 12
Imagine if we could do this
                           craziness in PHP



   @weaverryan
Thursday, May 24, 12
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 printed

Thursday, May 24, 12
Yep, that’s how it works in
                              JavaScript!



   @weaverryan
Thursday, May 24, 12
#1: Create a function

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




Thursday, May 24, 12
#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
#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
#3: Instantiate your new object


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




Thursday, May 24, 12
#4: Beers!




   @weaverryan
Thursday, May 24, 12
Princess Pro-tip

                    Your speaker is a
                    liar and a thief.
                   Using the prototype
                     is for sissies!



Thursday, May 24, 12
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
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
Bowser final word



                  Seriously, this is why I
                   fight against you guys




Thursday, May 24, 12
Bowser final word

             Your ignorance may seem
           blissful, but you work as a
              detriment towards the
             larger cause of evolving
                 and learning as
                    a community



Thursday, May 24, 12
Bowser final word


            Thank God Garrison Locke
           will be teaching us Object-
               oriented JavaScript
              tomorrow at 11:30 AM.




Thursday, May 24, 12
Bowser final word



             He’s a much better speaker
                    than this guy




Thursday, May 24, 12
Ryan does damage control
                     on his presentation


                       Dude, I’m right here




Thursday, May 24, 12
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
            presentation tomorrow if you
            want unreadable JavaScript


   @weaverryan
Thursday, May 24, 12
Mario’s bad JavaScript tip #4:



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


         http://bit.ly/php-js-demo
          04 - Scoping Concerns
   @weaverryan
Thursday, May 24, 12
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
With JavaScript objects, “this”
              may not always be what you
                       think it is



   @weaverryan
Thursday, May 24, 12
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
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
“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
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
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
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
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 extends
Thursday, May 24, 12
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
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
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
   @weaverryan
Thursday, May 24, 12
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
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
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
jQuery.live?


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


                             really just means this


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




Thursday, May 24, 12
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
   @weaverryan
Thursday, May 24, 12
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
JavaScript Real Life

         window.MagicBoxes = (function($) {

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

         MagicBoxes.someMethod();



Thursday, May 24, 12
This is just a function...

         window.MagicBoxes = (function($) {

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

         MagicBoxes.someMethod();



Thursday, May 24, 12
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
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
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
And that’s it!



        ‣ Makes isolated chunks of code

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



Thursday, May 24, 12
Backbone.js!




   @weaverryan
Thursday, May 24, 12
Mario’s bad JavaScript tip #8:


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


         http://bit.ly/php-js-demo
          08 - A Backbone View
   @weaverryan
Thursday, May 24, 12
What is Backbone?

          ‣ Set of tools for creating heavy front-
          end applications:
            * views
            * models
            * router



   @weaverryan
Thursday, May 24, 12
Views


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




Thursday, May 24, 12
Views


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




Thursday, May 24, 12
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
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
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
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
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
Models


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




Thursday, May 24, 12
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
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
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
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
Backbone is a great solution




Thursday, 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 already

          ‣ “Patterns” to follow as you get
          comfortable
   @weaverryan
Thursday, May 24, 12
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
   @weaverryan
Thursday, May 24, 12
When to use Models + Views


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



   @weaverryan
Thursday, May 24, 12
When *not* to use Models + Views



               ‣ An app where PHP renders HTML

               ‣ An app where the API isn’t robust


   @weaverryan
Thursday, May 24, 12
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

   @weaverryan
Thursday, May 24, 12
Duplication
               You can potentially duplicate a lot of
               work both on the client and server
               sides:
                       ‣ validation
                       ‣ models
                       ‣ templates

   @weaverryan
Thursday, May 24, 12
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 :)

   @weaverryan
Thursday, May 24, 12
Thanks...
                       Ryan Weaver
                       @weaverryan




Thursday, May 24, 12
... and we love you!
                         http://joind.in/talk/view/6508




                              Ryan Weaver
                              @weaverryan




        Ryan Weaver
        @weaverryan
Thursday, May 24, 12

More Related Content

Viewers also liked

Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and Webpack
Ignacio Martín
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful Security
Ryan Weaver
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)
Ryan Weaver
 
PHP + Node.js
PHP + Node.jsPHP + Node.js
PHP + Node.js
Patrick Kaminski
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
Ignacio Martín
 
Integrating Node.js with PHP
Integrating Node.js with PHPIntegrating Node.js with PHP
Integrating Node.js with PHP
Lee Boynton
 
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Ryan Weaver
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux Introduction
Nikolaus Graf
 
React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesome
Andrew Hull
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP Application
Andrew Rota
 
Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
Ignacio Martín
 

Viewers also liked (11)

Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and Webpack
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful Security
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)
 
PHP + Node.js
PHP + Node.jsPHP + Node.js
PHP + Node.js
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
 
Integrating Node.js with PHP
Integrating Node.js with PHPIntegrating Node.js with PHP
Integrating Node.js with PHP
 
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux Introduction
 
React JS and why it's awesome
React JS and why it's awesomeReact JS and why it's awesome
React JS and why it's awesome
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP Application
 
Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
 

More from Ryan Weaver

Webpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San FranciscoWebpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San Francisco
Ryan Weaver
 
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
Ryan Weaver
 
Grand Rapids PHP Meetup: Behavioral Driven Development with Behat
Grand Rapids PHP Meetup: Behavioral Driven Development with BehatGrand Rapids PHP Meetup: Behavioral Driven Development with Behat
Grand Rapids PHP Meetup: Behavioral Driven Development with Behat
Ryan Weaver
 
Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!
Ryan Weaver
 
Master the New Core of Drupal 8 Now: with Symfony and Silex
Master the New Core of Drupal 8 Now: with Symfony and SilexMaster the New Core of Drupal 8 Now: with Symfony and Silex
Master the New Core of Drupal 8 Now: with Symfony and Silex
Ryan Weaver
 
Silex: Microframework y camino fácil de aprender Symfony
Silex: Microframework y camino fácil de aprender SymfonySilex: Microframework y camino fácil de aprender Symfony
Silex: Microframework y camino fácil de aprender Symfony
Ryan Weaver
 
Drupal 8: Huge wins, a Bigger Community, and why you (and I) will Love it
Drupal 8: Huge wins, a Bigger Community, and why you (and I) will Love itDrupal 8: Huge wins, a Bigger Community, and why you (and I) will Love it
Drupal 8: Huge wins, a Bigger Community, and why you (and I) will Love it
Ryan Weaver
 
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other ToolsCool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Ryan Weaver
 
The Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsThe Wonderful World of Symfony Components
The Wonderful World of Symfony Components
Ryan Weaver
 
A PHP Christmas Miracle - 3 Frameworks, 1 app
A PHP Christmas Miracle - 3 Frameworks, 1 appA PHP Christmas Miracle - 3 Frameworks, 1 app
A PHP Christmas Miracle - 3 Frameworks, 1 app
Ryan Weaver
 
Symfony2: Get your project started
Symfony2: Get your project startedSymfony2: Get your project started
Symfony2: Get your project started
Ryan Weaver
 
Symony2 A Next Generation PHP Framework
Symony2 A Next Generation PHP FrameworkSymony2 A Next Generation PHP Framework
Symony2 A Next Generation PHP Framework
Ryan Weaver
 
Hands-on with the Symfony2 Framework
Hands-on with the Symfony2 FrameworkHands-on with the Symfony2 Framework
Hands-on with the Symfony2 Framework
Ryan Weaver
 
Being Dangerous with Twig (Symfony Live Paris)
Being Dangerous with Twig (Symfony Live Paris)Being Dangerous with Twig (Symfony Live Paris)
Being Dangerous with Twig (Symfony Live Paris)
Ryan Weaver
 
Being Dangerous with Twig
Being Dangerous with TwigBeing Dangerous with Twig
Being Dangerous with Twig
Ryan Weaver
 
Doctrine2 In 10 Minutes
Doctrine2 In 10 MinutesDoctrine2 In 10 Minutes
Doctrine2 In 10 Minutes
Ryan Weaver
 
Dependency Injection: Make your enemies fear you
Dependency Injection: Make your enemies fear youDependency Injection: Make your enemies fear you
Dependency Injection: Make your enemies fear you
Ryan Weaver
 
The Art of Doctrine Migrations
The Art of Doctrine MigrationsThe Art of Doctrine Migrations
The Art of Doctrine Migrations
Ryan Weaver
 

More from Ryan Weaver (18)

Webpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San FranciscoWebpack Encore Symfony Live 2017 San Francisco
Webpack Encore Symfony Live 2017 San Francisco
 
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
 
Grand Rapids PHP Meetup: Behavioral Driven Development with Behat
Grand Rapids PHP Meetup: Behavioral Driven Development with BehatGrand Rapids PHP Meetup: Behavioral Driven Development with Behat
Grand Rapids PHP Meetup: Behavioral Driven Development with Behat
 
Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!
 
Master the New Core of Drupal 8 Now: with Symfony and Silex
Master the New Core of Drupal 8 Now: with Symfony and SilexMaster the New Core of Drupal 8 Now: with Symfony and Silex
Master the New Core of Drupal 8 Now: with Symfony and Silex
 
Silex: Microframework y camino fácil de aprender Symfony
Silex: Microframework y camino fácil de aprender SymfonySilex: Microframework y camino fácil de aprender Symfony
Silex: Microframework y camino fácil de aprender Symfony
 
Drupal 8: Huge wins, a Bigger Community, and why you (and I) will Love it
Drupal 8: Huge wins, a Bigger Community, and why you (and I) will Love itDrupal 8: Huge wins, a Bigger Community, and why you (and I) will Love it
Drupal 8: Huge wins, a Bigger Community, and why you (and I) will Love it
 
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other ToolsCool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
 
The Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsThe Wonderful World of Symfony Components
The Wonderful World of Symfony Components
 
A PHP Christmas Miracle - 3 Frameworks, 1 app
A PHP Christmas Miracle - 3 Frameworks, 1 appA PHP Christmas Miracle - 3 Frameworks, 1 app
A PHP Christmas Miracle - 3 Frameworks, 1 app
 
Symfony2: Get your project started
Symfony2: Get your project startedSymfony2: Get your project started
Symfony2: Get your project started
 
Symony2 A Next Generation PHP Framework
Symony2 A Next Generation PHP FrameworkSymony2 A Next Generation PHP Framework
Symony2 A Next Generation PHP Framework
 
Hands-on with the Symfony2 Framework
Hands-on with the Symfony2 FrameworkHands-on with the Symfony2 Framework
Hands-on with the Symfony2 Framework
 
Being Dangerous with Twig (Symfony Live Paris)
Being Dangerous with Twig (Symfony Live Paris)Being Dangerous with Twig (Symfony Live Paris)
Being Dangerous with Twig (Symfony Live Paris)
 
Being Dangerous with Twig
Being Dangerous with TwigBeing Dangerous with Twig
Being Dangerous with Twig
 
Doctrine2 In 10 Minutes
Doctrine2 In 10 MinutesDoctrine2 In 10 Minutes
Doctrine2 In 10 Minutes
 
Dependency Injection: Make your enemies fear you
Dependency Injection: Make your enemies fear youDependency Injection: Make your enemies fear you
Dependency Injection: Make your enemies fear you
 
The Art of Doctrine Migrations
The Art of Doctrine MigrationsThe Art of Doctrine Migrations
The Art of Doctrine Migrations
 

Recently uploaded

Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
Pixlogix Infotech
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
Zilliz
 
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdfAI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
Techgropse Pvt.Ltd.
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
Kumud Singh
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
panagenda
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
Daiki Mogmet Ito
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Speck&Tech
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 
Things to Consider When Choosing a Website Developer for your Website | FODUU
Things to Consider When Choosing a Website Developer for your Website | FODUUThings to Consider When Choosing a Website Developer for your Website | FODUU
Things to Consider When Choosing a Website Developer for your Website | FODUU
FODUU
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”
Claudio Di Ciccio
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
Zilliz
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
IndexBug
 

Recently uploaded (20)

Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
 
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdfAI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
 
How to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For FlutterHow to use Firebase Data Connect For Flutter
How to use Firebase Data Connect For Flutter
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 
Things to Consider When Choosing a Website Developer for your Website | FODUU
Things to Consider When Choosing a Website Developer for your Website | FODUUThings to Consider When Choosing a Website Developer for your Website | FODUU
Things to Consider When Choosing a Website Developer for your Website | FODUU
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”“I’m still / I’m still / Chaining from the Block”
“I’m still / I’m still / Chaining from the Block”
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
 

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

  • 1. JAVASCRIPT BEST PRACTICES & BACKBONE.JS FOR THE PHP DEVELOPER Ryan Weaver @weaverryan Thursday, May 24, 12
  • 2. 7 tips for writing JavaScript like a jerk + What to take and leave in Backbone.js Thursday, May 24, 12
  • 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/weaverryan Thursday, May 24, 12
  • 4. Chapter 1: Java$criptQuery Look mom, I’m a JavaScript professional @weaverryan Thursday, May 24, 12
  • 5. 1. jQuery(document).ready(...) 2. 1500 lines, with deeply nested anonymous functions 3. Profit! $$$ @weaverryan Thursday, May 24, 12
  • 6. Too soon? ... sry fb, luv u kthxbye @weaverryan Thursday, May 24, 12
  • 7. The brains behind this presentation... Thursday, May 24, 12
  • 8. source: http://www.geeky-gadgets.com/super-mario-bros-matryoshka-dolls/ Thursday, May 24, 12
  • 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. 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. DEMO!!!!! http://bit.ly/php-js-demo 0 - The starting point Thursday, May 24, 12
  • 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-play Thursday, May 24, 12
  • 14. ‣ Click either .luigi or .peach ‣ the .luigi wrapper gets the active class Thursday, May 24, 12
  • 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 @weaverryan Thursday, May 24, 12
  • 17. Event Click! 1) You click! 2) An event travels up the tree Thursday, May 24, 12
  • 18. Browser event versus 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
  • 19. $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
  • 20. $luigi.click(function(event) { // ... }); Our listener is registered on .luigi Thursday, May 24, 12
  • 21. If you click .peach: event.target: .peach event.currentTarget: .luigi Thursday, May 24, 12
  • 22. If you click .luigi: event.target: .luigi event.currentTarget: .luigi Thursday, May 24, 12
  • 23. event.currentTarget == this * unless you screw with scope, which we’ll see! Thursday, May 24, 12
  • 24. $luigi.click(function(event) { // these are the same! $(event.currentTarget) .addClass('active'); $luigi.addClass('active'); }); Thursday, May 24, 12
  • 25. Preventing the damn “#” on the URL $luigi.click(function() { $(this).addClass('active'); return false; }); Thursday, May 24, 12
  • 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. ... but if you like your coworkers... $luigi.click(function(event) { event.preventDefault(); // ... }); The event keeps traveling up the DOM Thursday, May 24, 12
  • 28. Bad JavaScript moral #1: jQuery’s event object is a dangerous source of useful information and control @weaverryan Thursday, May 24, 12
  • 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 @weaverryan Thursday, May 24, 12
  • 30. A PHP object @weaverryan Thursday, May 24, 12
  • 31. <?php class MagicBoxes { public function initializeClick($wrapper) { // ... } } $magicBoxes = new MagicBoxes(); $magicBoxes->initializeClick('something'); Thursday, May 24, 12
  • 32. A JavaScript object @weaverryan Thursday, May 24, 12
  • 33. var MagicBoxes = { someProperty: 0, initializeClick: function($container) { // ... } }; MagicBoxes.initializeClick(something); Thursday, May 24, 12
  • 34. Just like with PHP, you can choose to organize your code into objects and functions @weaverryan Thursday, May 24, 12
  • 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. Princess Pro-tip Be careful with objects, they can increase readability, which threatens job security Thursday, May 24, 12
  • 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 reusable Thursday, May 24, 12
  • 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. 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. Bad JavaScript moral #2: Using global objects risks organizing your code into separate, distinct units @weaverryan Thursday, May 24, 12
  • 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 @weaverryan Thursday, May 24, 12
  • 42. Everything is an object Thursday, May 24, 12
  • 43. An object with a property var object1 = { fooProperty: 'foo!' } console.log(object1.fooProperty); // prints “foo!” Thursday, May 24, 12
  • 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. In PHP, we can create a class and then instantiate many instances @weaverryan Thursday, May 24, 12
  • 46. <?php class MagicBoxes { public function __construct($option) { // ... } } $magicBoxes1 = new MagicBoxes('foo'); $magicBoxes2 = new MagicBoxes('bar'); Thursday, May 24, 12
  • 47. How can we do this in JavaScript? @weaverryan Thursday, May 24, 12
  • 48. Imagine if we could do this craziness in PHP @weaverryan Thursday, May 24, 12
  • 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 printed Thursday, May 24, 12
  • 50. Yep, that’s how it works in JavaScript! @weaverryan Thursday, May 24, 12
  • 51. #1: Create a function window.MagicBoxes = function($container) { this.$el = $container; this.initialize(); }; Thursday, May 24, 12
  • 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. #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
  • 54. #3: Instantiate your new object jQuery(document).ready(function() { var $mario = $('.mario-world'); var magicBoxApp = new MagicBoxes($mario); }); Thursday, May 24, 12
  • 55. #4: Beers! @weaverryan Thursday, May 24, 12
  • 56. Princess Pro-tip Your speaker is a liar and a thief. Using the prototype is for sissies! Thursday, May 24, 12
  • 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 AM Thursday, May 24, 12
  • 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. Bowser final word Seriously, this is why I fight against you guys Thursday, May 24, 12
  • 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 community Thursday, May 24, 12
  • 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. Bowser final word He’s a much better speaker than this guy Thursday, May 24, 12
  • 63. Ryan does damage control on his presentation Dude, I’m right here Thursday, May 24, 12
  • 64. Purple is a manly color You really like that shirt... Thursday, May 24, 12
  • 65. Bad JavaScript moral #3: Don’t use jQuery’s prototype or go to Garrison Locke’s presentation tomorrow if you want unreadable JavaScript @weaverryan Thursday, May 24, 12
  • 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 @weaverryan Thursday, May 24, 12
  • 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. With JavaScript objects, “this” may not always be what you think it is @weaverryan Thursday, May 24, 12
  • 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. 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. “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. 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. 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
  • 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. 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 extends Thursday, May 24, 12
  • 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. 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. 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 @weaverryan Thursday, May 24, 12
  • 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. 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
  • 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. jQuery.live? $('.foo').live('click', ...); really just means this $('body').on('click', '.foo', ...); Thursday, May 24, 12
  • 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 @weaverryan Thursday, May 24, 12
  • 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. JavaScript Real Life window.MagicBoxes = (function($) { return { // do a bunch of craziness }; })(jQuery); MagicBoxes.someMethod(); Thursday, May 24, 12
  • 86. This is just a function... window.MagicBoxes = (function($) { return { // do a bunch of craziness }; })(jQuery); MagicBoxes.someMethod(); Thursday, May 24, 12
  • 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. 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. 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. And that’s it! ‣ Makes isolated chunks of code ‣ Used by most JavaScript libraries to isolate their code from yours Thursday, May 24, 12
  • 91. Backbone.js! @weaverryan Thursday, May 24, 12
  • 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 @weaverryan Thursday, May 24, 12
  • 93. What is Backbone? ‣ Set of tools for creating heavy front- end applications: * views * models * router @weaverryan Thursday, May 24, 12
  • 94. Views A formalized method for creating a JavaScript object that “manages” a DOM element Thursday, May 24, 12
  • 95. Views We’ve been building an object that’s very similar to a Backbone view Thursday, May 24, 12
  • 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. 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. 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. 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. 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. Models A formalized object that just holds key-value data on it Thursday, May 24, 12
  • 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. 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. 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. 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
  • 106. Backbone is a great solution Thursday, May 24, 12
  • 107. But do you have a problem? Thursday, May 24, 12
  • 108. Views: Easy win ‣ Easy event binding ‣ An object-oriented structure that’s setup for you already ‣ “Patterns” to follow as you get comfortable @weaverryan Thursday, May 24, 12
  • 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 @weaverryan Thursday, May 24, 12
  • 110. When to use Models + Views ‣ A highly interactive app that communicates to a PHP API that is never responsible for rendering any HTML @weaverryan Thursday, May 24, 12
  • 111. When *not* to use Models + Views ‣ An app where PHP renders HTML ‣ An app where the API isn’t robust @weaverryan Thursday, May 24, 12
  • 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 @weaverryan Thursday, May 24, 12
  • 113. Duplication You can potentially duplicate a lot of work both on the client and server sides: ‣ validation ‣ models ‣ templates @weaverryan Thursday, May 24, 12
  • 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 :) @weaverryan Thursday, May 24, 12
  • 115. Thanks... Ryan Weaver @weaverryan Thursday, May 24, 12
  • 116. ... and we love you! http://joind.in/talk/view/6508 Ryan Weaver @weaverryan Ryan Weaver @weaverryan Thursday, May 24, 12