Sunday, February 19, 2012

How to use RequireJS using JQuery with Object Oriented Structure


RequireJS is really a nice JavaScript file which helps to write Javascript in modular way . It helps to load dependencies when needed and optimizes code.
you can learn and check the requireJS main site. There has sample project on how to use requireJS with JQuery and I have used that project.
This http://requirejs.org/docs/jquery.html page discussed well about this project structures. I worked with Javascript in object oriented way before but faced problems with dependency loading. requireJS modular pattern solved my problem.
I have done little experiment on requireJS which I am sharing here.

When you will open the project's app.html file you will the following code
<script data-main="scripts/main" src="scripts/require-jquery.js"></script> 
the data-main attribute telling you there have main.js script where from your javascript program will start. In ASP.NET we sometimes write code in our .aspx page and start with jquery ready() method, we also use ASP.NET controls value as arguments. To check with that I have changed the <script> tag simple as referencing require-jquery.js file.
<script type="text/javascript" src="scripts/require-jquery.js"></script>

Now this looks as how we reference jquery.js. jquery is included in require-jquery.js for optimization so you do not need to reference jquery again. Now lets call jquery ready method in html file.
<script language="javascript" type="text/javascript"> 
require(["jquery"], function ($) {
            $(function () {
               
                        alert('<p>this is a text</p>');                 
               
            });
        });
 </script>
This will display alert message. require() method has first argument which is saying I need jquery inside this method. requireJS will load jquery and after that $(function(){}); method will run by query. So this is very easy to use. 
Now I want to encode my alert message. But I want to do in modular way. Here should have a helper class so that any function can use encoder and decoder and for that I want to create a static class “HtmlEncoder”. And other class which will need encoder or decoder will load this class before calling. For that I have created another class with name “HtmlEncoder.js” inside scripts folder. 
define( function (){

    return {
        Encode: function(value) {
            return $("<div/>").text(value).html();
        },

        Decode: function(value) {
            return $("<div/>").html(value).text();
        }
        
    };
});





and in the main app.html page just calling  the method like that
  require(["jquery"], function ($) {
             $(function () {

                require(["scripts/HtmlEncoder"], function (htmlEncoder) {
                    $("#button1").click(function () {
                       
                        alert( htmlEncoder.Encode('<p>this is a text</p>'));
                    });
                });

            });
        });
Here only a single object of HtmlEncoder will be created. if you call another function with same dependency of “scripts/HtmlEncoder” then you will not get new object. It will work as singleton object. But do I need to create always a .js file for every dependency as I have created HtmlEnoder.js file for defining HtmlEncoder. No, you do not need to create .js file for defining a class. Youcan create definition without create a .js file for that. For that you need to give a name of definition. Let create HtmlEncoder in app.html page. 
    define("HtmlEncoder", {
             id:1,
            Encode: function (value) {
                return $("<div/>").text(value).html() + require('HtmlEncoder').id++;
            },

            Decode: function (value) {
                return $("<div/>").html(value).text();
            }


        });


As this is define in app.html so you can give dependency as follows:
 require(["jquery"], function ($) {
             $(function () {

                require(["HtmlEncoder"], function (htmlEncoder) {
                    $("#button1").click(function () {
                       
                        alert( htmlEncoder.Encode('<p>this is a text</p>'));
                    });
                });

            });
        });
Here in require statement I have mention only “HtmlEncoder” so it will find definition inside app.html. and load this instance.Also you can see I have created this little different way as we usually create a static class in javascript. and both give single object.
 
But I want to create different object for my definition. For that you need to define a constructor function and return the constructor. 
Lets create another file Employee.js and code like bellow :
define(function () {
    function Employee() {
        return {
            Id: 1,
            Name: "name",

            Roll: "roll",
            getEmployee: function () {

                return this.Name + this.Roll + this.Id++;
            }
        };
    }
    return (Employee);
});
 
Here you can see Employee constructor is defined and also returned. Now using this constructor we can create different objects of Employee class.

Now lets call the require method with Employee and create new instance of employee. 
 require(["jquery"], function ($) {
             $(function () {
                require(["scripts/HtmlEncoder", "scripts/Employee"], function (HtmlEncoder, Employee) {
                        var employee1 = new Employee();
                        var encodedValue = HtmlEncoder.Encode("<p>this is value</p>");
                        alert(encodedValue);
                        alert(HtmlEncoder.Encode(employee1.getEmployee()));
                  
                });
      });
});
HtmlEncoder is working as static here but as I have defined contructor for Employee so I can now create new instance for Employee object. 
 
Here I have tried to represent RequireJS in simple way through simple example by calling jquery inside app.html page but there have Advanced feature in RequireJS which you will find in requireJS documentation. I have tried to demonstrate how we can use HtmlEnoder like helper method. and also how  define can be created without without creating another .js file. Also created another definition with constructor function for creating multiple instance.

No comments:

Post a Comment