Links to the other posts in this series
In Part 1 I looked at what an ASP.NET AJAX control is and the basic building blocks of such controls, the Sys.Component, Sys.UI.Behavior and Sys.UI.Control types. Let's look at what these types offer us:
Sys.Component is the base class for the other two types and implements (amongst other things):
Let's take a look at a definition of a component. Conveniently, in Visual Studio 2008 / ASP.NET 3.5 there is a new item template for both a behavior and a control:
If I opt for a behavior, this is what I get (NB to change this or a control definition to a component is a trivial task):
Type.registerNamespace("WebSite1"); WebSite1.ClientBehavior = function(element) { WebSite1.ClientBehavior.initializeBase(this, [element]); } WebSite1.ClientBehavior.prototype = { initialize: function() { WebSite1.ClientBehavior.callBaseMethod(this, 'initialize'); // Add custom initialization here }, dispose: function() { //Add custom dispose actions here WebSite1.ClientBehavior.callBaseMethod(this, 'dispose'); } } WebSite1.ClientBehavior.registerClass('WebSite1.ClientBehavior', Sys.UI.Behavior); if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
If you're well acquainted with JavaScript this probably looks pretty familiar. If not, it may look a little daunting. Let me try and explain. Firstly, the ASP.NET AJAX client framework allows me to register namespaces just as I can in .NET. We can then break down out component definition into 3 parts; constructor, class definition and registration.
You can think of the Website1.ClientBehavior assignment as the equivalent of a .NET constructor. Each time we create an instance of our ClientBehavior class that anonymous function code will be executed giving us an opportunity to perform any actions required (including initialising the base class with a call to initializeBase()).
The JavaScript prototype model is used to allow us to create a definition that can be re-used or cloned multiple times. Every object in JavaScript has a prototype object that it inherits from. Defining properties on the ClientBehavior's prototype object ensures these properties are shared across all instances. Defining methods here makes them available to every instance of our component. If we define a field in the prototype that value is also shared across all instances; not necessarily what we want. If we want an instance variable, we should define it in the constructor and expose it via property getters and setters in the prototype. We'll see all this in action shortly.
Finally we register our new type with ASP.NET AJAX via the call to registerClass() specifying the base type (in this case Sys.UI.Behavior). The last line of code ensures that we notify the ScriptManager that we're done so it can carry on with its next action.
Now this all sounds a bit complicated but in essence, if you start with the template it's pretty straightforward to modify to achieve what you want. I should say this all holds true for ASP.NET 2.0 with the ASP.NET AJAX Extensions as well (though you'll need to manually copy the templates from somewhere as I don't think you get the new item templates in Visual Studio).
Let's take the template above and modify it to be a basic Sys.Component that helps us to see the component lifecycle:
Type.registerNamespace("DevWeek"); DevWeek.SimpleComponent = function() { DevWeek.SimpleComponent.initializeBase(this); alert('Simple Component Constructor'); } DevWeek.SimpleComponent.prototype = { initialize: function() { DevWeek.SimpleComponent.callBaseMethod(this, 'initialize'); // Add custom initialization here alert('Simple Component Initialising'); }, dispose: function() { //Add custom dispose actions here alert('Simple Component Disposing'); DevWeek.SimpleComponent.callBaseMethod(this, 'dispose'); } } DevWeek.SimpleComponent.registerClass('DevWeek.SimpleComponent', Sys.Component); if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
Notice there are a few alerts() in there which will hopefully help us to understand what's going on. But before we get there we need to know how to create and use one of these things. Well there's nothing stopping you creating an instance provided you perform the right sequence of steps but there is a create() helper method on the Sys.Component type (with a $create shortcut) that does the hard work for you.
So to create an instance of our new DevWeek.SimpleComponent class all I need to do is make a call to $create during Sys.Application.init (the initialisation event of the Sys.Application object). In our case this would be something as simple as:
Sys.Application.add_init(pageInit); function pageInit() { $create(DevWeek.SimpleComponent, // class {}, // properties {}, // events {}, // references null); // associated element }
ie we add a handler to the Sys.Application.init event and in there call $create passing the type of component we want to create as the first parameter. Other parameters on $create allow us to set property values, hook up event handlers, add references to other components and associate our component with a DOM element on the page (to be used with behaviors and controls).
Sys.Component.create() does a number of things:
If we create a simple aspx page as follows
<%@ Page Language="C#" %> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Simple Component</title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> <Scripts> <asp:ScriptReference Path="~/Component.js" /> </Scripts> </asp:ScriptManager> <script type="text/javascript"> Sys.Application.add_init(pageInit); function pageInit() { $create(DevWeek.SimpleComponent, // class {}, // properties {}, // events {}, // references null); // associated element } </script> </form> </body> </html>
and save our component definition in a file called Component.js then when we run the page we'll see two alerts "Simple Component Constructor" (we're in the constructor code) and "Simple Component Initialising" (in the initialise method). Navigate away from the page or close the browser and the "Simple Component Disposing" (in the dispose method) alert will pop-up.
Next on the list is accessing the components we've created as well as adding properties and events. We're at the stage now where we can start to use my control from the launch session to illustrate some of these concepts and ultimately build them into an ASP.NET AJAX server control you can just drop onto an aspx page.
Maybe it's be a good idea for me to list the previous parts in each of these posts for easy reference
Let's take a quick look at the control I created for the launch event. By adding an instance of my VEMapControl
Links to the rest of this series Building ASP.NET AJAX Controls (Pt 1) Building ASP.NET AJAX Controls
As requested, it's probably easiest to create and maintain an index post and link to that from all the
【原文地址】 March 28th Links: ASP.NET, ASP.NET AJAX, ASP.NET MVC, Visual Studio, Silverlight, .NET 【原文发表日期
Collegamenti del 28 Marzo, ASP.NET, ASP.NET AJAX, ASP.NET MVC, Visual Studio, Silverlight, .NET
Aqui está a última versão da minha lista de links . Verifique também minha página de Dicas, Truques e