Showing posts with label asp.net ajax. Show all posts
Showing posts with label asp.net ajax. Show all posts

Mar 16, 2009

Function.createDelegate

function greet(message) {
        alert(message + ", " + this.name);
    }

    var instance = { name: "fred" };
    
    //when you create a delegate, "this" in the delegate function body
    //refer to the instance passed in
    var greetSomeone = Function.createDelegate(instance, greet);
    greetSomeone("hello");
    /*
    Function.createDelegate = function Function$createDelegate(instance, method) {
    /// 
    /// 
    /// 
    /// 
    var e = Function._validateParams(arguments, [
        { name: "instance", mayBeNull: true },
        { name: "method", type: Function }
    ]);
    if (e) throw e;
    return function() {
        return method.apply(instance, arguments);
    }
}

Function.createCallback

   var createCallback = function(method, context) {
    return function() {
        //the arguements is passed in when the this callback
        //method is call
        //if there is parameter passed
        //package the parameter with the context
        //into an array, an invoke the callback
        //method with the array
        var l = arguments.length;
        if (l > 0) {
            var args = [];
            for (var i = 0; i < l; i++) {
                args[i] = arguments[i];
            }
            //the last array member is the 
            //the context
            args[l] = context;

            //apply with array argument 
            return method.apply(this, args);
        }

        //if there is no parameters 
        //just invoke the callback method with
        // the context as the only parameter
        return method.call(this, context);
    }
}

function eat(foodName, animalName) {
    alert(animalName + " eat " + foodName);
}

function Animal(name) {
    if (!name) {
        this.name = name;
    }
    else {
        this.name = "animal";
    }

    //eat is the function will be called
    //name is the predetermined pass-in parameter
    //this parameter will be the last parameter in the function
    //the order paraemeter will be passed in when the callback is called
    this.eat = createCallback(eat, name);
}

var a = new Animal("fred");
//"grass" is passed in when callback is called
a.eat("grass");

Mar 23, 2008

difference between behavior and controls in asp.net

The differences between controls and behaviors are mostly semantic. Both are components associated with DOM elements in the page, and they offer a similar set of features. Behaviors enhance DOM elements without changing the base func- tionality they provide. If you associate a behavior with a text box element, the text field continues to accept the user’s text input. But you can use the behavior to add client functionality to the text box and, for example, upgrade it to an auto-com- plete text box.

The chief purpose of client controls is creating element wrappers. For example, you can create a TextBox control that wraps an input element of type text. You can create a Label control that wraps a span element, and so on. This is similar to what happens with the ASP.NET TextBox and Label server controls. The differ- ence is that they wrap DOM elements on the server side rather than on the client side. An element wrapper can be useful to enhance the way you program against a DOM element. For example, you can use controls as a way to program against DOM elements using declarative code.

A fundamental difference between behaviors and controls is that a DOM ele- ment can have multiple behaviors, but it can be associated with one and only one control. For this reason, behaviors are best suited to add client capabilities to a DOM element in an incremental way. On the other hand, a control is supposed to provide the whole client functionality to its associated element.

Mar 5, 2008

Sys.UI.Control

Conceptually, a control differs from a behavior in the sense that instead of just providing client functionality, a control usually represents or wraps the element, to provide additional properties and methods that extend its programming interface.

            Type.registerNamespace('Samples');
            Samples.EmptyControl = function(element) {
            Samples.EmptyControl.initializeBase(this, [element]);
            }
            Samples.EmptyControl.prototype = {
            initialize : function() {
            Samples.EmptyControl.callBaseMethod(this, 'initialize');
            },
            dispose : function() {
            Samples.EmptyControl.callBaseMethod(this, 'dispose');
            }
            }
            Samples.EmptyControl.registerClass('Samples.EmptyControl',
            Sys.UI.Control);

            //creating controls
            $create(Samples.EmptyControl, {}, {}, {}, $get('elementID'));
            

Because controls are client components, you can access them with the $find method. However, the Id of control can't be set programatically. It is automatically set by the SysUI.Control calss to the same ID as the associated element. You can get a reference to the control by passing the ID of the associated DOM element to $find. Another way to access a control is through the associated element. Because an element can have one or only one associated control, a property called "control", which stores the reference to the control - is created on the DOM element when the control is initialized. Supposing that you have a DOM element stored in the someElement variable, the following statement accesses the associated control arne stores a reference in the controlInstance variable.

            var controlInstance = someElement.control;
            

Below is textbox control's implementation code

            Type.registerNamespace('Samples');

            // Samples.TextBox class.
            Samples.TextBox = function(element) {
            Samples.TextBox.initializeBase(this, [element]);

            this._ignoreEnterKey = false;
            }
            Samples.TextBox.prototype = {
            // Component lifecycle.
            initialize : function() {
            Samples.TextBox.callBaseMethod(this, 'initialize');

            // Subscribe to the keypress event.
            $addHandlers(this.get_element(),
            {keypress:this._onKeyPress}, this);
            },

            dispose : function() {
            // Detach event handlers.
            $clearHandlers(this.get_element());

            Samples.TextBox.callBaseMethod(this, 'dispose');
            },

            // Handle the keypress event.
            _onKeyPress : function(evt) {
            if(this._ignoreEnterKey && evt.charCode == 13) {
            evt.preventDefault();
            }
            },

            // Properties.
            get_ignoreEnterKey : function() {
            return this._ignoreEnterKey;
            },

            set_ignoreEnterKey : function(value) {
            this._ignoreEnterKey = value;
            }
            }
            Samples.TextBox.registerClass('Samples.TextBox', Sys.UI.Control);

            //at the client side
            Sys.Application.add_init(pageInit);
            function pageInit() {
            $create(Samples.TextBox, {'ignoreEnterKey':true}, {}, {},
            $get('myTextBox'));
            }
            

Sys.UI.Behavior

            Type.registerNamespace('Samples');
            Samples.EmptyBehavior = function(element) {
            Samples.EmptyBehavior.initializeBase(this, [element]);
            }
            Samples.EmptyBehavior.prototype = {
            initialize : function() {
            Samples.EmptyBehavior.callBaseMethod(this, 'initialize');
            },
            dispose : function() {
            Samples.EmptyBehavior.callBaseMethod(this, 'dispose');
            }
            }
            Samples.EmptyBehavior.registerClass('Samples.EmptyBehavior',
            Sys.UI.Behavior);

            //Creating behavior

            $create(Samples.EmptyBehavior, {'name':'myEmptyBehavior'}, {}, {},
            $get('elementID'));

            //accessing behaviors
            var instance = $find('someElement$myEmptyBehavior');
            //or
            var emptyBehaviorInstance = $get('someElement').myEmptyBehavior;
            
            Type.registerNamespace('Samples');

            // Samples.FormattingBehavior class.
            Samples.FormattingBehavior = function(element) {
            Samples.FormattingBehavior.initializeBase(this, [element]);

            // Fields.
            this._hoverCssClass = null;
            this._focusCssClass = null;
            this._currentCssClass = null;
            this._mouseOver = null;
            this._focus = null;
            }
            Samples.FormattingBehavior.prototype = {
            // Component lifecycle.
            initialize : function() {
            Samples.FormattingBehavior.callBaseMethod(this, 'initialize');
            //this is changing the
            //the behavior of the associated
            //element
            //get_element is inherit from parent.

            $addHandlers(this.get_element(),
            {
            mouseout:this._onMouseout,
            mouseover:this._onMouseover,
            focus:this._onFocus,
            blur:this._onBlur
            }, this);
            },

            dispose : function() {
            $clearHandlers(this.get_element());

            Samples.FormattingBehavior.callBaseMethod(this, 'dispose');
            },

            // Event handlers.
            _onMouseover : function() {
            this._mouseOver = true;
            this._setCssClass();
            },

            _onMouseout : function() {
            this._mouseOver = false;
            this._setCssClass();
            },

            _onFocus : function() {
            this._focus = true;
            this._setCssClass();
            },

            _onBlur : function() {
            this._focus = false;
            this._setCssClass();
            },

            // Helper method.
            _setCssClass : function() {
            if (this._currentCssClass) {
            Sys.UI.DomElement.removeCssClass(this._element,
            this._currentCssClass);
            this._currentCssClass = null;
            }

            if (this._error) {
            this._currentCssClass = this._errorCssClass;
            }
            else if (this._focus) {
            this._currentCssClass = this._focusCssClass;
            }
            else if (this._mouseOver) {
            this._currentCssClass = this._hoverCssClass;
            }

            if (this._currentCssClass) {
            Sys.UI.DomElement.addCssClass(this._element,
            this._currentCssClass);
            }
            },

            // Properties.
            get_hoverCssClass : function() {
            return this._hoverCssClass;
            },

            set_hoverCssClass : function(value) {
            this._hoverCssClass = value;
            },

            get_focusCssClass : function() {
            return this._focusCssClass;
            },

            set_focusCssClass : function(value) {
            this._focusCssClass = value;
            }
            }
            // Inherit from Sys.UI.Behavior.
            Samples.FormattingBehavior.registerClass('Samples.FormattingBehavior', Sys.UI.Behavior);


            //add the client side we attached the behavior to element
            Sys.Application.add_init(pageInit);

            function pageInit(sender, e) {
            // Attach the FormattingBehavior to the txtName textbox.
            $create(Samples.FormattingBehavior,
            {'hoverCssClass':'field_hover', 'focusCssClass':'field_focus'},
            {}, {}, $get('Name'));

            // Attach the FormattingBehavior to the txtLastName textbox.
            $create(Samples.FormattingBehavior,
            {'hoverCssClass':'field_hover', 'focusCssClass':'field_focus'},
            {}, {}, $get('LastName'));
            }
            //$create function will automatically call the initialize method.
            

expose event in asp.net ajax

  1. Create a method that adds an event handler.
  2. Create a method that removes an event handler.
  3. Create a method that is responsible for raising the event.
            Type.registerNamespace('Samples');

            Samples.Collection = function() {
            this._innerList = [];

            // Store an instance of Sys.EventHandlerList.
            this._events = null;
            }
            Samples.Collection.prototype = {
            // Add an item to the collection.
            add : function(member) {
            this._innerList.push(member);

            // Raise the itemAdded event.
            this._raiseEvent('itemAdded', Sys.EventArgs.Empty);
            },

            // Return the Sys.EventHandlerList instance.
            get_events : function() {
            if(!this._events) {
            this._events = new Sys.EventHandlerList();
            }

            return this._events;
            },

            // Add an handler for the itemAdded event.
            add_itemAdded : function(handler) {
            this.get_events().addHandler('itemAdded', handler);
            },

            // Remove an handler for the itemAdded event.
            remove_itemAdded : function(handler) {
            this.get_events().removeHandler('itemAdded', handler);
            },

            // Generic function to raise an event.
            _raiseEvent : function(eventName, eventArgs) {
            var handler = this.get_events().getHandler(eventName);

            if (handler) {
            if (!eventArgs) {
            eventArgs = Sys.EventArgs.Empty;
            }
            handler(this, eventArgs);
            }
            }
            }
            Samples.Collection.registerClass('Samples.Collection');
            

The same process applies to client components that want to expose events. The only difference is that you don't need to store an instance of Sys.EventHandlersList class in the constructor, because every component inherits it from the base Sys.Component class. You also inherit the get_events method shown above.

Additionally, components expose an event called propertyChanged that can be raised whenever the value of a property changes. This mechanism is useful because you don't have to expose and raise a custom event for each value you want to monitor. Instead you rely on the propertyChanged event, defined in the SysINotifyPropertyChange interface. Whenever the value exposed by a property changes, all you have to do is call the raisePropertyChanged method. This method accepts a string with the name of the property whose value has changed. Below is an example.

            Type.registerNamespace('Samples');
            Samples.Customer = function() {
            Samples.Customer.initializeBase(this);
            this._fullName;
            }
            Samples.Customer.prototype = {
            get_fullName : function() {
            return this._fullName;
            },
            set_fullName : function(value) {
            if(value != this._fullName) {
            this._fullName = value;
            this.raisePropertyChanged('fullName');
            }
            }
            }
            Samples.Customer.registerClass('Samples.Customer', Sys.Component);

            //at the client side you use the following code to subscribe the event as below.

            function pageLoad(sender, e) {
            var customer = new Samples.Customer();
            customer.add_propertyChanged(onPropertyChanged);
            customer.set_fullName('John Doe');
            }

            function onPropertyChanged(sender, e) {
            if(e.get_propertyName() == 'fullName') {
            alert('New value for the fullName property: ' +
            sender.get_fullName());
            }
            }
            

Mar 2, 2008

cancel request vs abort reqeust

In asp.net ajax framework, you can cancel request before the request is submitted to the server, you can aborted the request after the request is submitted to the server and before the response is received.

function onInitializeRequest(sender, args){
    var prm = Sys.WebForms.PageRequestManager.getInstance();
    if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'CancelRefresh') {
            prm.abortPostBack();
    }else if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') {
            args.set_cancel(true);
            ActivateAlertDiv('visible', 'Still working on previous request.');
            }
            else if (!prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') {
            ActivateAlertDiv('visible', 'Retrieving headlines.');
            }

Feb 25, 2008

Dynamically adding control which can do async postback in UpdatePanel

Precondition, The control needs to have Id, if not the ajax clientside script can not handle it. Then see the following code.

Dim btn As LinkButton = CType(child, LinkButton)
AddHandler btn.Click, AddressOf ProcessFilter
''me.UpdatePanel1.Triggers.Add(as
'Dim trigger As UpdatePanelControlTrigger = New UpdatePanelControlTrigger
Dim trigger As AsyncPostBackTrigger = New AsyncPostBackTrigger()
trigger.ControlID = btn.UniqueID
trigger.EventName = "Click"
Me.UpdatePanel1.Triggers.Add(trigger)

Aug 27, 2007

javascript delegate callback

In c#, you can create a delegate like the code below.
            class Animal
            {
            public string Greeting = "Hello,";
            public void Greet(string message)
            {
            Console.WriteLine(this.Greeting + message);
            }

            }

            class Client
            {
            public SampleDelegate TestDelegate;
            public void Demo()
            {
            Animal a = new Animal();
            TestDelegate = new SampleDelegate(a.Greet);
            TestDelegate("Ainmal");
            }
            }
            
But in javascript , "this" is in the context of caller. In asp.net ajax library, there is a function to create a delegate.
            Function.createDelegate = function Function$createDelegate(instance, method)
            {
            /// 
            /// 
            /// 
            var e = Function._validateParams(arguments, [
            {name: "instance", mayBeNull: true},
            {name: "method", type: Function}
            ]);
            if (e) throw e;
            //it is not the same as return method.apply(instance, arguments);
            return function() {
            return method.apply(instance, arguments);
            }
            }
            
Please note that is return a function pointer, and the function call the method in the context of instance.
            function pageLoad() {
            // test is a property of the window object.
            this.test = "I'm a test string!";

            // Create a delegate that points to onButtonClick and pass the
            // window object as the first argument.
            var clickDelegate = Function.createDelegate(this, onButtonClick);

            // Handle the click event with the delegate.
            $addHandler($get('testButton'), 'click', clickDelegate);

            //if we call,   $addHandler($get('testButton'), 'click', onButtonClick);
            // the "this" inside of the method will reference to  button, and its
            //test value is null

            }

            function onButtonClick() {
            // Access the window object.
            alert(this.test);
            }
            
The Function.createDelegate method is useful because you don’t have to store in a global variable—or even in a DOM element—the context that you want to access in the event handler.
            $addHandlers(buttonElement, { click:onButtonClick,
            mouseover:onMouseOver }, this);
            //"this" is context inside of event
            
Callback function in asp.net ajax library is similar to delegate, but they solve a different problem. Delegate solve the problem of "this" context, so that it accept instance parameter, the "this" will refer to instance. "this" in Callback function is still in the context of caller. But Callback function accept a context parameter. Both concept is very useful in ajax, because it is all about reuse. The section of code can be reuse in different "conext"!
            Function.createCallback = function Function$createCallback(method, context) {
            /// 
            /// 
            /// 
            var e = Function._validateParams(arguments, [
            {name: "method", type: Function},
            {name: "context", mayBeNull: true}
            ]);
            if (e) throw e;



            return function() {
            var l = arguments.length;
            if (l > 0) {
            var args = [];
            for (var i = 0; i < l; i++) {
            args[i] = arguments[i];
            }
            args[l] = context;
            return method.apply(this, args);
            }
            return method.call(this, context);
            }
            }

            //example
            function pageLoad() {
            // The context object.
            var context = { date : new Date() };

            // Create a callback that points to onButtonClick and pass
            // the context object.
            var clickCallback =
            Function.createCallback(onButtonClick, context);

            // Attach a handler to the click event of the button.
            $addHandler($get('myButton'), 'click', clickCallback);
            }

            function onButtonClick(evt, context) {
            // Here we can access both the event object and
            // the context.
            var loadTime = context.date;
            var elapsed = new Date() - loadTime;
            alert(this);
            alert((elapsed / 1000) + ' seconds');
            }
            

Aug 10, 2007

ASP.NET AJAX EVENTS

Sys.Component Event

disposing Event

Raised when the dispose method of the current Component object is called.

propertyChanged Event

Raised when the raisePropertyChanged method of the current Component object is called.

Sys.Application Event

init Event

Raised after all scripts have been loaded but before objects are created.

load Event

Raised after all scripts have been loaded and after the objects in the application have been created and initialized.

unload Event

Raised before all objects in the client application are disposed.

Sys.WebForms.PageRequestManager Event

beginRequest Event

Raised before processing of an asynchronous postback starts and the postback request is sent to the server.

endRequest Event

Raised after an asynchronous postback is finished and control has been returned to the browser.

initializeRequest Event

Raised during the initialization of the asynchronous postback.

pageLoaded Event

Raised after all content on the page is refreshed as the result of either a synchronous or an asynchronous postback.

pageLoading Event

Raised after the response from the server to an asynchronous postback is received but before any content on the page is updated.

Aug 7, 2007

Creating asp.net ajax class

            
            
            
            ASP.NET AJAX Class
            
            
            

Notice that the local members are accessed with a prefix of this. The script engine can then scope the lookup to the type and avoid searching any containing scopes. If you do not use this to indicate that the reference is local to the type, you will end up creating objects in the global scope and see errors that can be confusing and time-consuming to track down.

The call to registerClass looks a little odd, as it is on the type being registered. The prototype of the base type in JavaScript has been modified to add type-system support. Once the type is registered, an instance of it can be created and its members called.

The registerClass function actually has three possible parameters: The first one is for the name of the type, the second is for the base type being extended, and the last is to specify any interfaces that the class implements. Instances of using these classes are provided in later examples in this chapter.

JavaScript treats parameters as optional. This can be convenient. Instead of needing to define a bunch of different methods with different names in order to accommodate different combinations of parameters, you can write just one that knows how to process all of the optional inputs. Because the language treats all parameters as optional, however, you need to explicitly check that the inputs are valid for what you are doing. The caller can invoke the function with whatever set of parameters it wants to pass.

            
            
            
            ASP.NET AJAX Class
            
                

The constructor must explicitly call initializeBase and pass itself, using the this keyword, along with an array of the arguments to pass to the constructor of the base type. The AJAX Library allows you to employ object-oriented principles, but doing so requires that you follow some coding patterns like this. Without the call to initializeBase, when you try to call something on the base type, you will get an error. In Internet Explorer, the message reads: Object doesn't support this property or method. This is not the most helpful message! In Firefox, it fails silently, but if you have the JavaScript console open, an error message is displayed that more explicitly identifies the actual problem: anotherAlbum.get_title is not a function

The call to initializeBase takes care of producing the final type with inheritance semantics in place. The base class constructor is called with the arguments provided. The type system of the AJAX Library also provides some reflection functions that let you explore the relationship between objects.

            if(Wrox.ASPAJAX.Samples.TributeAlbum.isInstanceOfType(anAlbum) == false) {
            alert("anAlbum is not a TributeAlbum");
            }

            if (Wrox.ASPAJAX.Samples.TributeAlbum.isInstanceOfType(anotherAlbum) == true) {
            alert("anotherAlbum is a TributeAlbum");
            }

            if (Wrox.ASPAJAX.Samples.TributeAlbum.inheritsFrom(Wrox.ASPAJAX.Samples.Album) ==
            true ) {
            alert("TributeAlbum inherits from Album");
            }

            if (Wrox.ASPAJAX.Samples.Album.inheritsFrom(Wrox.ASPAJAX.Samples.TributeAlbum) ==
            true) {
            alert("Album does not inherit from TributeAlbu7");
            }

            

At first glance, the type references in Listing 4-6 look long. JavaScript doesn’t have the equivalent of the using statement that makes namespaces available to code without being explicit. With a compiled language, the cost of the lookup can be paid when the binary is created and symbolic references are created. In an interpreted language like JavaScript, you can speed up the lookup by providing a shortcut for the long type name by providing aliases that reference the fully qualified name. When you create global object aliases, you defeat the purpose of the namespace containers. Each subsequent lookup can get a little more expensive for every item in the checked scope. The ideal time to create aliases is when something is going to be referenced frequently and you can alias it temporarily, when it will soon go out of scope and the alias will be cleaned up. If the code in Listing 4-6 were going to be run frequently, or if it contained many more calls to the types, it would probably be worth caching a reference to the type and avoid the repeated lookups. Creating a local alias is easy; just declare a variable and assign the type to it. Listing 4-7 demonstrates creating and using aliases for the Album and TributeAlbum types.

            var tributeAlbum = Wrox.ASPAJAX.Samples.TributeAlbum;
            var album = Wrox.ASPAJAX.Samples.Album;

            if(tributeAlbum.isInstanceOfType(anAlbum) == false) {
            alert("anAlbum is not a TributeAlbum");
            }

            if (tributeAlbum.isInstanceOfType(anotherAlbum) == true) {
            alert("anotherAlbum is a TributeAlbum");
            }

            if (tributeAlbum.inheritsFrom(album) == true) {
            alert("TributeAlbum inherits from Album");
            }

            if (album.inheritsFrom(tributeAlbum) == true) {
            alert("Album does not inherit from TributeAlbum");
            }
            

The AJAX library provides a method for explicitly calling a base method implementation. This is often used when a derived type wants to take the result from the base type and modify it before returning it to the caller. It is not limited to calling into the base type from a derived type’s implementation. You can also call a base method for an object. In a language like C++, you can cast an object to its base type to access a specific method implementation. Likewise, this pattern in JavaScript lets you access the base method even though JavaScript can’t support the casting semantic for this purpose. In Listing 4-8 (from CallBase.aspx), the TributeAlbum class adds an override for the get_artist method. It calls the base implementation and then prepends it with "TRIBUTE: " before returning it. This is again a slight modification to the previous example of the example using Album and TributeAlbum types

            Wrox.ASPAJAX.Samples.TributeAlbum.prototype = {
            get_tributeArtist: function() {
            return this._tributeArtist;
            },
            set_tributeArtist: function(tributeArtist) {
            this._tributeArtist = tributeArtist;
            },
            get_artist: function() {
            return ("TRIBUTE: " +
            Wrox.ASPAJAX.Samples.TributeAlbum.callBaseMethod(this, "get_artist"));
            }
            }

            

asp.net ajax namespace

            
            
            
            ASP.NET AJAX Namespaces
            
            
            

The call to Type.registerNamespace creates three different objects: Wrox, ASPAJAX, and Samples. The Wrox object contains the ASPAJAX object, which in turn contains the Samples object. The objects all carry some metadata so the type system can identify them as namespaces and use them to hold any other objects that are added to the namespace. The Type.isNamespace function returns a Boolean. The code didn’t create an Album namespace, so for that check, it returns false. The set of global namespaces is retrieved by calling Type.getRootnamespaces. Looping through the returned array and calling getName on each reveals that, in addition to the new Wrox namespace, there is also a Sys namespace. It contains the AJAX Library functionality. Although doing so is not technically required, I recommend using namespaces to organize your own code, even if just to avoid cluttering up the global namespace. Because JavaScript is an interpreter language, the operation of resolving names is expensive. Every time you call a function, the JavaScript engine has to figure out where the code lives. Resolving variables also involves searching the current scope and containing scopes until the reference is resolved. The more global objects you have, the more expensive it is for the script engine to access them. Namespace objects also allow navigating to classes in the hierarchy more readily than would happen in a flat global arrangement. Thus, namespaces offer a performance benefit as well as providing a programmer convenience for grouping functionality. Namespaces by themselves, however, are not much use until your create classes in them that will provide useful functionality.

Aug 5, 2007

Reflection

            var g = new Demo.Trees.GrannySmith();
            var gt = Demo.Trees.GrannySmith;
            var a = new Array(
            Demo.Trees.Apple,
            Demo.Trees.Tree,
            Demo.Trees.Pine,
            Demo.Trees.IFruitTree,
            Sys.IContainer);

            function OnButton1Click()
            {
            for (var i = 0; i < a.length; i ++)
            {
            if (a[i].isInstanceOfType(g))
            {
            alert(gt.getName() + " is a " + a[i].getName() + ".");
            }
            else alert(gt.getName() + " is not a " + a[i].getName() + ".");
            }
            }

            function OnButton2Click()
            {
            for (var i = 0; i < a.length; i ++)
            {
            if (gt.inheritsFrom(a[i]))
            {
            alert(gt.getName() + " inherits from " + a[i].getName() + ".");
            }
            else alert(gt.getName() + " does not inherit from " + a[i].getName() + ".");
            }
            }

            function OnButton3Click()
            {
            for (var i = 0; i < a.length; i ++)
            {
            if (Type.isInterface(a[i]))
            {
            if (gt.implementsInterface(a[i]))
            {
            alert(gt.getName() + " implements the " + a[i].getName() + " interface.");
            }
            else alert(gt.getName() + " does not implement the " + a[i].getName() + " interface.");
            }
            else alert(a[i].getName() + " is not an interface.");
            }
            }

            

Register namespace, and class

            Type.registerNamespace("Demo");

            Demo.Person = function(firstName, lastName, emailAddress) {
            this._firstName = firstName;
            this._lastName = lastName;
            this._emailAddress = emailAddress;
            }

            Demo.Person.prototype = {

            getFirstName: function() {
            return this._firstName;
            },

            getLastName: function() {
            return this._lastName;
            },

            getName: function() {
            return this._firstName + ' ' + this._lastName;
            },

            dispose: function() {
            alert('bye ' + this.getName());
            }
            }
            Demo.Person.registerClass('Demo.Person', null, Sys.IDisposable);

            // Notify ScriptManager that this is the end of the script.
            if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

            

Type, window.Type, Function


            Function.__typeName = 'Function';
            Function.__class = true;

            //....

            window.Type = Function;
            window.__rootNamespaces = [];
            window.__registeredTypes = {};

            

Jul 31, 2007

Sys.Component

Generally, the term component denotes an object that is reusable and can interact with other objects in the context of a framework. The term control, on the other hand, denotes an object that is sort of a specialized component. The main trait that differentiates components and controls is the user interface. Components are non-UI objects; controls are primarily UI-based objects. In the Microsoft AJAX library, the root component class is Sys.Component. The root class for controls is named Control and, guess what, lives in the Sys.UI namespace. In the Microsoft AJAX library, Sys.UI.Control derives from Sys.Component.

            

Sys.Application

The execution of each asp.net ajax page is controlled by an application object that is intstantiated in the body of the library. Whenever an asp.net ajax page is loaded in the browser, an instance of Sys._Application class is promptly created and assigned to the Sys.Application object: Sys.Application = new Sys._Application();

In additional, each asp.net ajax page is injected with the following script code:

            
            

This code is placed immediately after the closing tag of the of the page's form, and it commands the loading of any script files registered for loading with the page's script manager. Sys._Application class derives from Compnent and is the entry point point in the page hierachy to locate client-side components either bound to server controls or programmatically added to the application.

Member

Description

addComponent

Adds the specified Microsoft AJAX library component to the page hierarchy

beginCreateComponents

Starts adding new Microsoft AJAX library components to the page

endCreateComponents

Ends adding new Microsoft AJAX library components to the page

findComponent

Looks up the specified Microsoft AJAX library component in the page

getComponents

Gets the list of Microsoft AJAX library components found in the page

initialize

Ensures that all referenced script files are loaded

notifyScriptLoaded

Called by script files to notify the application object that the script has been successfully loaded

queueScriptReference

Queues a new script reference for loading

removeComponent

Removes the specified component from the page hierarchy

Vents in the page lifetime

Event

Description

Init

Occurs when the page is first initialized

Load

Occurs when the page is loaded

loadTimedOut

Occurs when the loading step takes too much time to complete

scriptLoadFailed

Occurs when one script fails to load for whatever reason

Unload

Occurs when the page is unloaded

Client Page Life-cycle Events

Create Custom ASP.NET AJAX Non-Visual Client Components

Components

  • Derive from the component base class
  • Typically have no UI representation, such as timer component that raise events at intervals but is not visible on the page.
  • Have no associated DOM elements
  • Encapsulate client code that is intended to be resuable across applications

Behavior

  • Derive from the behavior base class, wich extend the Component base class
  • Extend the behavior of DOM elements, such as a watermarking behavior of the DOM element that they are associated with.
  • Can create UI elements, although they do not typically modified the basic of DOM element that they are associated with.
  • If assigned an ID, can be accessed directly from the DOM element through a custom attribute( expando).
  • Do not require an association with another client object, such as a class derived from the Control or Behavior classes.
  • Can reference either a control or a non-control HTML element in their element property.

Controls

  • Derive from the Control base class, which extends the Component base class.
  • Represent a DOM element as a client object, typically changing the original DOM element's ordinary behavior to provide new functionality. For example, a menu control might read >li< items from a >ul< element as its source data, but not display a bulleted list.
  • Are accessed from the DOM element directly through the control expando

Please refer this artical, in summary you need to do the following thing

  • You need to create an component in js file
  • add reference to the js file
  • create the component instance in the application load event, the instance will be associated with other element in the page because the information is passed in the creation method.

            Type.registerNamespace("Demo");

            Demo.Timer = function() {
            Demo.Timer.initializeBase(this);
            this._interval = 1000;
            this._enabled = false;
            this._timer = null;}

            Demo.Timer.prototype = {

            // OK to declare value types in the prototype
            get_interval: function() {
            /// Interval in milliseconds
            return this._interval;    },

            set_interval: function(value) {
            if (this._interval !== value) {
            this._interval = value;
            this.raisePropertyChanged('interval');
            if (!this.get_isUpdating() && (this._timer !== null))
            {
            this._restartTimer();
            }        }    },

            get_enabled: function() {
            /// True if timer is enabled, false if disabled.
            return this._enabled;    },

            set_enabled: function(value) {
            if (value !== this.get_enabled()) {
            this._enabled = value;
            this.raisePropertyChanged('enabled');

            if (!this.get_isUpdating())
            {
            if (value) {
            this._startTimer();                }                else {
            this._stopTimer();                }            }        }
            },    // events    add_tick: function(handler) {
            /// Adds a event handler for the tick event.
            /// The handler to add to the event.
            this.get_events().addHandler("tick", handler);    },
            remove_tick: function(handler) {
            /// Removes a event handler for the tick event.
            /// The handler to remove from the event.
            this.get_events().removeHandler("tick", handler);    },
            dispose: function() {
            // call set_enabled so the property changed event fires, for potentially attached listeners.
            this.set_enabled(false);
            // make sure it stopped so we aren't called after disposal
            this._stopTimer();        // be sure to call base.dispose()
            Demo.Timer.callBaseMethod(this, 'dispose');    },
            updated: function() {        Demo.Timer.callBaseMethod(this, 'updated');
            // called after batch updates, this.beginUpdate(), this.endUpdate().
            if (this._enabled) {            this._restartTimer();        }    },
            _timerCallback: function() {
            var handler = this.get_events().getHandler("tick");
            if (handler) {            handler(this, Sys.EventArgs.Empty);        }
            },    _restartTimer: function() {        this._stopTimer();
            this._startTimer();    },    _startTimer: function() {
            // save timer cookie for removal later
            this._timer = window.setInterval(Function.createDelegate(this, this._timerCallback), this._interval);
            },    _stopTimer: function() {        if(this._timer) {
            window.clearInterval(this._timer);            this._timer = null;
            }    }}
            // JSON object that describes all properties, events, and methods of this component that should
            // be addressable through the Sys.TypeDescriptor methods, and addressable via xml-script.
            Demo.Timer.descriptor = {    properties: [   {name: 'interval', type: Number},
            {name: 'enabled', type: Boolean} ],
            events: [ {name: 'tick'} ]}
            Demo.Timer.registerClass('Demo.Timer', Sys.Component);
            // Since this script is not loaded by System.Web.Handlers.ScriptResourceHandler
            // invoke Sys.Application.notifyScriptLoaded to notify ScriptManager
            // that this is the end of the script.
            if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
            

ASP.NET AJAX Life Cycle

  1. Sys.Application.init(event handle need Sys.Application.add_init(MyInit);
  2. Sys.Application.load (event handler function pageLoad(sender, args){}
  3. Sys.Application.unload (event handler function pageUnLoad(sender, args){}
  4. Sys.Application.disposing( inherit from Component class)
  5. Sys.Application.propertyChanged( inherit from Component class)
  1. Sys.WebForms.PageRequestManager.initializeRequest
  2. Sys.WebForms.PageRequestManager.beginRequest
  3. Sys.WebForms.PageRequestManager.pageLoading
  4. Sys.WebForms.PageRequestManager.pageLoaded
  5. Sys.WebForms.PageRequestManager.endRequest

For detail see this

            Sys.Application.add_init(applicationInit);
            //Sys.Application.add_load(applicationLoad);
            Sys.Application.add_unload(applicationUnload);

            function applicationInit(sender, args)
            {
            alert("application init");
            }

            function pageLoad(sender, args) {
            //function applicationLoad(sender, args) {
            alert("application load");
            }

            function applicationUnload(sender, args)
            {
            alert("application unload");
            }

            Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(pageRequestInitRequestHandler);
            Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(pageRequestManagerBeginRequestHandler);
            Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(pageReqeustPageLoading);
            Sys.WebForms.PageRequestManager.getInstance().add_endRequest(pageRequestManagerEndRequestHandler);
            Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageRequestManagerLoadHandler);

            function pageRequestInitRequestHandler(sender, args)
            {
            alert("PageRequestManager initRequest");
            }

            function pageReqeustPageLoading(sender, args)
            {
            alert("PageRequestManager pageLoading");
            }

            function pageRequestManagerBeginRequestHandler(sender, args)
            {
            alert("PageRequestManager beginRequestr");
            }

            function pageRequestManagerLoadHandler(sender, args)
            {
            alert("PageRequestManager pageLoaded");
            }

            function pageRequestManagerEndRequestHandler(sender, args)
            {
            alert("PageRequestManager endRequest");
            }
            

For the initial load, the event sequence is PageRequestManager pageLoaded, application init, application load. For asynchronous call, is PageRequestManager initRequest, PageRequestManager beginRequest, PageRequestManager pageLoading, PageRequestManager pageLoaded, application load, PageRequestManager endRequest.

ASP.NET AJAX WebRequest

            // Instantiate a WebRequest.
            var wRequest = new Sys.Net.WebRequest();

            // Set the request URL.
            wRequest.set_url("getTarget.htm");

            // Set the request verb.
            wRequest.set_httpVerb("GET");

            // Set the request callback function.
            wRequest.add_completed(OnWebRequestCompleted);


            // Execute the request.
            wRequest.invoke();

            // This callback function processes the
            // request return values. It is called asynchronously
            // by the current executor.
            function OnWebRequestCompleted(executor, eventArgs)
            {
            if(executor.get_responseAvailable())
            {
            // Clear the previous results.

            resultElement.innerHTML = "";

            // Display Web request status.
            resultElement.innerHTML +=
            "Status: [" + executor.get_statusCode() + " " +
            executor.get_statusText() + "]" + "
"; // Display Web request headers. resultElement.innerHTML += "Headers: "; resultElement.innerHTML += executor.getAllResponseHeaders() + "
"; // Display Web request body. resultElement.innerHTML += "Body:"; if(document.all) resultElement.innerText += executor.get_responseData(); else resultElement.textContent += executor.get_responseData(); } }