ASP.NET AJAX Programmer’s Reference - Chapter 7 pot

62 280 0
ASP.NET AJAX Programmer’s Reference - Chapter 7 pot

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Component Development Infrastructure The ASP.NET and .NET Frameworks provide server-side programmers with the necessary infrastructure for component development. You can think of a component as a unit of functionality that implements a well-known API. A component may or may not have a visual presence in the user interface of an application. For example, a timer is a component that does not render visual markup in an ASP.NET page. A GridView , on the other hand, is a component that does render visual markup in a page. Thanks to the ASP.NET and .NET component development infrastructure, you can develop components such as GridView with minimal time and effort. The ASP.NET AJAX client-side framework provides client-side programmers with a component- development infrastructure that emulates its ASP.NET and .NET counterparts to enable you to develop client-side components with minimal time and effort. The ASP.NET AJAX component-development infrastructure consists of a set of well-defined interfaces and classes as discussed in this chapter. First, this chapter presents the main interfaces that make up the ASP.NET AJAX component- development infrastructure. Then the chapter introduces two main classes of this infrastructure: Component and _Application . Every ASP.NET AJAX component (including your own custom components) directly or indirectly derives from the Component base class. This base class defines the lifecycle that every component application must go through. A component lifecycle consists of well-defined phases, as discussed in this chapter. Therefore, deriving your custom component classes from the Component base class automatically enables your component to participate in a typical component lifecycle. Every ASP.NET AJAX application is represented by an instance of the _Application class. This instance is created by the ASP.NET AJAX framework and exposed through the Sys.Application variable. The _Application class defines the lifecycle that every ASP.NET AJAX application must go through. An application lifecycle consists of well-defined phases, as discussed in this chapter. c07.indd 219c07.indd 219 8/20/07 8:09:02 PM8/20/07 8:09:02 PM Chapter 7: Component Development Infrastructure 220 Interfaces The ASP.NET AJAX client-side framework extends the core functionality of JavaScript to add support for object-oriented features such as classes, inheritance, enumerations, interfaces, and so on. Interfaces are at the heart of every object-oriented framework. They act as contracts between the classes that implement them and the clients of these classes. This allows you to replace the existing classes with new ones with- out affecting the client code as long as the new classes honor the established contract by implementing the required interfaces. The ASP.NET and .NET Frameworks come with well-known sets of interfaces that are used throughout these frameworks and the ASP.NET and .NET applications. The ASP.NET AJAX client-side framework includes a set of interfaces that emulate their ASP.NET and .NET counterparts. These interfaces are used throughout the ASP.NET AJAX client-side framework and the ASP.NET AJAX applications. The following sections cover some of these interfaces. I Disposable The .NET Framework defines an interface named IDisposable that exposes a single method named Dispose . Every .NET class that holds valuable resources must implement this interface, and the class’s implementation of the Dispose method must release the resources that it holds. The Dispose method of a .NET class instance is invoked right before the instance is disposed of. The ASP.NET AJAX client-side framework includes an interface named IDisposable that emulates the .NET IDisposable interface as shown in Listing 7-1 . The ASP.NET AJAX IDisposable interface, just like its .NET counterpart, exposes a single method named dispose . Note that this interface belongs to the Sys namespace. Listing 7-1: The I Disposable Interface Sys.IDisposable = function Sys$IDisposable() { throw Error.notImplemented(); } function Sys$IDisposable$dispose() { throw Error.notImplemented(); } Sys.IDisposable.prototype = { dispose: Sys$IDisposable$dispose } Sys.IDisposable.registerInterface(‘Sys.IDisposable’); Listing 7-2 references a JavaScript file named Monitor.js that contains the code for a class that implements the IDisposable interface. This file defines a class named Monitor whose main purpose is to monitor mouse movement and display the x and y coordinates of the mouse pointer as it is moving. c07.indd 220c07.indd 220 8/20/07 8:09:02 PM8/20/07 8:09:02 PM Chapter 7: Component Development Infrastructure 221 Listing 7-2: A Class that Implements the I Disposable Interface <%@ Page Language=”C#” %> <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml”> <head runat=”server”> <title>Untitled Page</title> <script type=”text/javascript” language=”javascript”> function pageLoad() { var monitor = new Disposables.Monitor(); var btn = $get(“btn”); var disposeDelegate = Function.createDelegate(monitor, monitor.dispose); $addHandler(btn, “click”, disposeDelegate); } </script> </head> <body> <form id=”form1” runat=”server”> <asp:ScriptManager ID=”ScriptManager1” runat=”server” > <Scripts> <asp:ScriptReference Path=”Monitor.js” /> </Scripts> </asp:ScriptManager> <button id=”btn” type=”button”>Dispose Monitor</button> <div> </div> </form> </body> </html> Listing 7-3 presents the contents of the Monitor.js JavaScript file. Listing 7-3: The Monitor.js JavaScript File Type.registerNamespace(“Disposables”); Disposables.Monitor = function() { this.div = document.createElement(“div”); document.body.insertBefore(this.div,document.forms[0]); this.registerMonitor(); } (continued) c07.indd 221c07.indd 221 8/20/07 8:09:03 PM8/20/07 8:09:03 PM Chapter 7: Component Development Infrastructure 222 Listing 7-3 (continued) Disposables.Monitor.prototype = { registerMonitor : function() { this.delegate = Function.createDelegate(this, this.print); $addHandler(document, “mousemove”, this.delegate); }, print : function(domEvent) { this.div.innerHTML = ”X-Coordinate: “ + domEvent.clientX + “<br/>” + “Y-Coordinate: “ + domEvent.clientY; }, dispose : function() { $removeHandler(document, “mousemove”, this.delegate); } } Disposables.Monitor.registerClass(“Disposables.Monitor”, null, Sys.IDisposable); if(typeof(Sys)!==’undefined’) Sys.Application.notifyScriptLoaded(); The Monitor.js first defines a namespace named Disposables : Type.registerNamespace(“Disposables”); Next, it defines the constructor of the Monitor class. Note that the Monitor class belongs to the Disposables namespace. This constructor first creates the <div> HTML element that will display the x and y coordinates of the mouse pointer: this.div = document.createElement(“div”); Next, it inserts this <div> HTML element before the <form> HTML element: document.body.insertBefore(this.div,document.forms[0]); Finally, the constructor calls the registerMonitor method of the Monitor class: this.registerMonitor(); The Monitor.js file then defines the instance methods of the Monitor class. The first instance method is the registerMonitor method. The registerMonitor method first calls the createDelegate static method on the Function class to create a delegate that represents the Monitor object’s print method: this.delegate = Function.createDelegate(this, this.print); c07.indd 222c07.indd 222 8/20/07 8:09:03 PM8/20/07 8:09:03 PM Chapter 7: Component Development Infrastructure 223 Next, the registerMonitor method calls the addHandler static method on the DomEvent class to register the delegate as the event handler for the document object’s mousedown event: $addHandler(document, “mousemove”, this.delegate); Next, the Monitor.js file defines the print instance method of the Monitor class. The print method takes an argument of type DomEvent that represents the event object. The print method prints the values of the clientX and clientY properties of the DomEvent object within the opening and closing tags of the <div> HTML element: this.div.innerHTML = ”X-Coordinate: “ + domEvent.clientX + “<br/>” + “Y-Coordinate: “ + domEvent.clientY; The Monitor.js file then defines the dispose method of the Monitor class. As discussed earlier, the dispose method of a class instance is where the class instance must do the final cleanup before the instance is disposed of. In this case, the Monitor object removes the event handler that it registered for the document object’s mousemove event: dispose : function() { $removeHandler(document, “mousemove”, this.delegate); } Next, the Monitor.js file registers the Monitor class with the ASP.NET AJAX client-side framework. Note that it passes Sys.IDisposable as the third argument to the registerClass method to inform the framework that the class being registered (the Monitor class) implements the Sys.IDisposable interface: Disposables.Monitor.registerClass(“Disposables.Monitor”, null, Sys.IDisposable); As you can see in the following excerpt from Listing 7-2 , the pageLoad method first creates an instance of the Monitor class: var monitor = new Disposables.Monitor(); Next, the pageLoad method calls the createDelegate method on the Function class to create a delegate that represents the dispose method of the newly created Monitor object: var disposeDelegate = Function.createDelegate(monitor, monitor.dispose); Finally, the pageLoad method calls the addHandler static method on the DomEvent class to register the delegate as the event handler for the click event of the specified <button> DOM element: var btn = $get(“btn”); $addHandler(btn, “click”, disposeDelegate); When you click the <button> HTML element shown in Figure 7-1 , the disposeDelegate delegate is automatically invoked. The delegate then calls the dispose method of the Monitor object, which in turn removes the event handler that the Monitor object had registered for the document object’s mousemove event. Therefore, after clicking the <button> HTML element, the monitor will no longer keep track of the mouse movement. c07.indd 223c07.indd 223 8/20/07 8:09:03 PM8/20/07 8:09:03 PM Chapter 7: Component Development Infrastructure 224 This example explicitly calls the dispose method. This was done for educational purposes. As you’ll see later, the ASP.NET AJAX client-side framework provides you with an infrastructure that automatically calls the dispose method of a component when the component is about to be disposed of. I NotifyDisposing As discussed in the previous section, your ASP.NET AJAX client classes must implement the IDisposable interface to perform final cleanup such as releasing the resources they’re holding before they’re disposed of. There are times when the client of an instance of an ASP.NET AJAX client class needs to be notified when the instance is about to be disposed of — that is, when the dispose method of the instance is invoked. To address these cases, your ASP.NET AJAX client classes must also implement the INotifyDisposing interface as defined in Listing 7-4 . This interface exposes the following two methods: ❑ add_disposing : Your ASP.NET AJAX client class’s implementation of this method must register the specified event handler as the callback for the disposing event. Your class must raise this event when its dispose method is invoked. ❑ remove_disposing : Your ASP.NET AJAX client class’s implementation of this method must remove the specified event handler from the list of event handlers registered for the disposing event. Listing 7-4: The I NotifyDisposing Interface Sys.INotifyDisposing = function Sys$INotifyDisposing() { throw Error.notImplemented(); } function Sys$INotifyDisposing$add_disposing(handler) { throw Error.notImplemented(); } Figure 7-1 c07.indd 224c07.indd 224 8/20/07 8:09:04 PM8/20/07 8:09:04 PM Chapter 7: Component Development Infrastructure 225 function Sys$INotifyDisposing$remove_disposing(handler) { throw Error.notImplemented(); } Sys.INotifyDisposing.prototype = { add_disposing: Sys$INotifyDisposing$add_disposing, remove_disposing: Sys$INotifyDisposing$remove_disposing } Sys.INotifyDisposing.registerInterface(“Sys.INotifyDisposing”); Listing 7-5 presents the content of the new version of the Monitor.js JavaScript file for the new version of the Monitor class that implements the INotifyDisposing interface. Listing 7-5: The new version of the Monitor.js JavaScript file Type.registerNamespace(“Disposables”); Disposables.Monitor = function() { this.div = document.createElement(“div”); document.body.insertBefore(this.div,document.forms[0]); this.registerMonitor(); } Disposables.Monitor.prototype = { registerMonitor : function() { this.delegate = Function.createDelegate(this, this.print); $addHandler(document, “mousemove”, this.delegate); }, print : function(domEvent) { this.div.innerHTML = ”X-Coordinate: “ + domEvent.clientX + “<br/>” + “Y-Coordinate: “ + domEvent.clientY; }, dispose : function() { if (this.events) { var handler = this.events.getHandler(“disposing”); if (handler) handler(this, Sys.EventArgs.Empty); } delete this.events; $removeHandler(document, “mousemove”, this.delegate); }, (continued) c07.indd 225c07.indd 225 8/20/07 8:09:04 PM8/20/07 8:09:04 PM Chapter 7: Component Development Infrastructure 226 Listing 7-5 (continued) get_events : function() { if (!this.events) this.events = new Sys.EventHandlerList(); return this.events; }, add_disposing : function(handler) { this.get_events().addHandler(“disposing”, handler); }, remove_disposing : function(handler) { this.get_events().removeHandler(“disposing”, handler); } } Disposables.Monitor.registerClass(“Disposables.Monitor”, null, Sys.IDisposable, Sys.INotifyDisposing); if(typeof(Sys)!==’undefined’) Sys.Application.notifyScriptLoaded(); As you can see in this listing, the new version of the Monitor class implements the following three new methods: ❑ get_events : This method returns a reference to an EventHandlerList object. This object will be used to store the JavaScript functions that the Monitor object’s clients register as event handlers for the events the Monitor class exposes. Currently the Monitor class exposes a single event: disposing . get_events : function() { if (!this.events) this.events = new Sys.EventHandlerList(); return this.events; } ❑ add_disposing : This method provides the Monitor class’s implementation of the add_disposing method of the INotifyDisposing interface. This method calls the addHandler method on the EventHandlerList object ( this.events ) to register the specified handler for the disposing event: add_disposing : function(handler) { this.get_events().addHandler(“disposing”, handler); } c07.indd 226c07.indd 226 8/20/07 8:09:04 PM8/20/07 8:09:04 PM Chapter 7: Component Development Infrastructure 227 ❑ remove_disposing : This method provides the Monitor class’s implementation of the remove_disposing method of the INotifyDisposing interface. This method calls the removeHandler method on the EventHandlerList object to remove the specified handler: remove_disposing : function(handler) { this.get_events().removeHandler(“disposing”, handler); } Listing 7-6 presents a page that uses the new version of the Monitor class. Note that the pageLoad method calls the Monitor object’s add_disposing method to register the disposingcb JavaScript function as the event handler for the object’s disposing event: monitor.add_disposing(disposingcb); When you click the Dispose Monitor button to call the Monitor object’s dispose method, it automatically invokes the disposingcb JavaScript function. Listing 7-6: A Page that Uses the New Version of the Monitor Class <%@ Page Language=”C#” %> <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml”> <head runat=”server”> <title>Untitled Page</title> <script type=”text/javascript” language=”javascript”> function disposingcb() { alert(“The Disposing event was raised!”); } function pageLoad() { var monitor = new Disposables.Monitor(); monitor.add_disposing(disposingcb); var btn = $get(“btn”); var disposeDelegate = Function.createDelegate(monitor, monitor.dispose); $addHandler(btn, “click”, disposeDelegate); } </script> </head> <body> <form id=”form1” runat=”server”> <asp:ScriptManager ID=”ScriptManager1” runat=”server”> (continued) c07.indd 227c07.indd 227 8/20/07 8:09:05 PM8/20/07 8:09:05 PM Chapter 7: Component Development Infrastructure 228 Listing 7-6 (continued) <Scripts> <asp:ScriptReference Path=”Monitor.js” /> </Scripts> </asp:ScriptManager> <button id=”btn” type=”button”>Dispose Monitor</button> <div> </div> </form> </body> </html> I NotifyPropertyChanged If the clients of an instance of your ASP.NET AJAX client class need to be notified when one or more of the properties of the instance change value, your class must implement the INotifyPropertyChange interface as defined in Listing 7-7 . Listing 7-7: The I NotifyPropertyChanged Interface Sys.INotifyPropertyChange = function Sys$INotifyPropertyChange() { throw Error.notImplemented(); } function Sys$INotifyPropertyChange$add_propertyChanged(handler) { throw Error.notImplemented(); } function Sys$INotifyPropertyChange$remove_propertyChanged(handler) { throw Error.notImplemented(); } Sys.INotifyPropertyChange.prototype = { add_propertyChanged: Sys$INotifyPropertyChange$add_propertyChanged, remove_propertyChanged: Sys$INotifyPropertyChange$remove_propertyChanged } Sys.INotifyPropertyChange.registerInterface(‘Sys.INotifyPropertyChange’); As you can see, the INotifyPropertyChange interface exposes the following two methods: ❑ add_propertyChanged : Your ASP.NET AJAX client class’s implementation of this method must register the specified handler as the event handler for the propertyChanged event. Your class must raise this event when one of its properties changes value. c07.indd 228c07.indd 228 8/20/07 8:09:05 PM8/20/07 8:09:05 PM [...]... class The ASP.NET AJAX Component base class plays a similar role in the ASP.NET AJAX client-side framework An ASP.NET AJAX component is an ASP.NET AJAX client class that directly or indirectly derives from the ASP.NET AJAX Component base class; and deriving directly or indirectly from this base class is what makes an ASP.NET AJAX component a component 2 37 c 07. indd 2 37 8/20/ 07 8:09:08 PM Chapter 7: Component... interface The ASP.NET AJAX client-side framework includes an interface named IContainer that emulates the NET IContainer interface ASP.NET AJAX components can be contained in any ASP.NET AJAX container as long as the container implements the ASP.NET AJAX IContainer interface Keep in mind that this container may or may not be a visual container Listing 7- 1 2 presents the definition of the ASP.NET AJAX IContainer... lifecycle of an ASP.NET AJAX component, let’s go back to the endCreateComponents and raiseLoad methods of the Application object to finish the journey with Application endCreateComponents Listing 7- 2 7 presents the internal implementation of the endCreateComponents method of the Application object 253 c 07. indd 253 8/20/ 07 8:09:13 PM Chapter 7: Component Development Infrastructure Listing 7- 2 7: The endCreateComponents... IDisposable, INotifyDisposing, and INotifyPropertyChange interfaces This class simply encapsulates the logic that other ASP.NET AJAX client classes such as Monitor would have to re-implement otherwise 235 c 07. indd 235 8/20/ 07 8:09: 07 PM Chapter 7: Component Development Infrastructure Listing 7- 1 1: The Component Class Sys.Component = function Sys$Component() { // More code to come } function Sys$Component$get_events()... shown in Listing 7- 1 3 The name of this class has been prefixed with an underscore to emphasize that the ASP.NET AJAX applications are not allowed to instantiate this class The ASP.NET AJAX client-side framework automatically instantiates a single instance of the _Application class when an ASP.NET AJAX application is loaded The framework defines a variable named Sys.Application that references this singular... /> Dispose Monitor Figure 7- 2 Figure 7- 3 232 c 07. indd 232 8/20/ 07 8:09:06 PM Chapter 7: Component Development Infrastructure The new version of the Monitor class exposes the following five new methods (as shown in Listing 7- 8 ): ❑ add_propertyChanged: This method provides the Monitor class’s implementation of the add_propertyChanged... changes value Because many ASP.NET AJAX client classes need to offer these three features, the ASP.NET AJAX clientside framework includes a base class named Component that implements these three interfaces Therefore, any ASP.NET AJAX client class that derives from the Component class automatically offers these three features without having to re-implement them As Listing 7- 1 1 shows, the Component class... MicrosoftAjax.js JavaScript file is loaded into the memory of the browser This file includes the following statement, which invokes the constructor of the _Application class: Sys.Application = new Sys._Application(); 243 c 07. indd 243 8/20/ 07 8:09:09 PM Chapter 7: Component Development Infrastructure Listing 7- 1 8 presents the internal implementation of the _Application class constructor Listing 7- 1 8: The... their journey through their life-cycle phases The Component base class defines the typical lifecycle of an ASP.NET AJAX application’s component 248 c 07. indd 248 8/20/ 07 8:09:11 PM Chapter 7: Component Development Infrastructure The lifecycle of a component begins when the create method of the Component base class is invoked to instantiate the component, as shown in Listing 7- 2 2 The main responsibility... setter calls the raisePropertyChanged method to raise the propertyChanged event Listing 7- 1 0 presents the internal implementation of the PropertyChangedEventArgs event data class As you can see, this class, like any other ASP.NET AJAX event data class, derives from the EventArgs 234 c 07. indd 234 8/20/ 07 8:09: 07 PM Chapter 7: Component Development Infrastructure base class It exposes a single method, \ get_propertyName, . inherits the .NET Component base class. The ASP. NET AJAX Component base class plays a similar role in the ASP. NET AJAX client-side frame- work. An ASP. NET AJAX component is an ASP. NET AJAX client. the logic that other ASP. NET AJAX client classes such as Monitor would have to re-implement otherwise. c 07. indd 235c 07. indd 235 8/20/ 07 8:09: 07 PM8/20/ 07 8:09: 07 PM Chapter 7: Component Development. interfaces. The ASP. NET and .NET Frameworks come with well-known sets of interfaces that are used throughout these frameworks and the ASP. NET and .NET applications. The ASP. NET AJAX client-side framework

Ngày đăng: 09/08/2014, 06:23

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan