Saturday 23 November 2013

Sunday 17 November 2013

Backbone.js Event

Backbone Events are an important concept in Backbone, since they provide you with an easy mechanism to use the pub sub pattern and decouple your code. Backbone triggers certain events by default (eg. a Model change event is triggered after a Model property has been validated and saved), but Backbone also allows you to trigger and bind to custom events. This is an extremely useful pattern, since it allows many different classes to listen to one class, without that one class knowing about any of its listeners.
Here is an example Event being triggered by a Backbone Model class:
 var Model = Backbone.Model.extend({

        // Default properties
        defaults: {

            example: "I love having my data separated from the DOM"

        }

        // Constructor
        initialize: function() {

        },

        // Any time a Model attribute is set, this method is called
        validate: function(attrs) {

        },

        triggerEvent: function() {

            // Triggers an test event and passes data that can be accessed in the event handler
            this.trigger("test", { someData: "data" });

        }

    });
Here is an example Event being bound by a Backbone View class:

var view = Backbone.View.extend({

        // Represents the actual DOM element that corresponds to your View (There is a one to one relationship between View Objects and DOM elements)
        el: 'body',

        // Constructor
        initialize: function() {

            //Setting the view's model property.  This assumes you have created a model class and stored it in the Model variable
            this.model = new Model();

            //Event handler that calls the initHandler method when the init Model Event is triggered
            this.model.on("test", this.test);

        },

        // Event Handlers
        events: {

            "click #example": "testModelEvent"

        },

        render: function() {

            // Updates the text of the element with an ID attribute of example            
            this.$el.find("#example").text("This is an example");

        },

        promptUser: function() {

            prompt("Isn't this great?", "Yes, yes it is");

        },

        testModelEvent: function() {
            this.model.triggerEvent();
        },

        test: function(obj) {

            console.log("Just got " + obj.someData + " from my model!");

        }

    });

Backbone.js Event Conclusion
The basic functionality that a Backbone Event class object provides is a mechanism for using the pub/sub pattern to decouple an application’s codebase. 99.9% of applications could benefit from a design pattern that promotes decouplization (not sure if that is a real word).
A common jQuery design pattern is triggering and binding to jQuery special events on the HTML body element. This pattern is extremely useful, but Backbone improves on this pattern, since it does not rely on the DOM for its pub/sub implementation. This improves performance and flexibility, since it allows you to bind to custom events on a generic JavaScript object instead of just a jQuery object.
No matter the complexity of your application, the Backbone Events class object could very easily promote decoupling your code and consistent special event binding.

Wednesday 13 November 2013

Use closures to keep variable declarations short in Backbone View


This tip applies to JavaScript more broadly, and thus isn't limited to Backbone. We all know that letting variables slip up into the global scope is a Bad Thing. This is why it's important to declare all variables using the varkeyword at the top of each function. (Due to variable hoisting in JavaScript, variables defined anywhere in a function are hoisted to the top when it's executed, so always declare them at the top to avoid sad surprises). In complex functions, the list of local variables at the top can grow unruly. To keep variable declarations closer to where they're actually used in the code, use anonymous functions to give yourself an inline local scope:
myNamespace.myView = Backbone.View.extend({
  render: function() {
    var height = 110,
          width = 340,
          is_nested_row = false,
          // tons of other local variables
          render_footer = true;

      // time to format footer. keep local footer vars close to implementation
          (function() {
            var outer_height = 234,
                  background_color = red;

             $footer.height(outer_height).css('background', background_color);
          })();

  }
});