ASP.NET AJAX Programmer’s Reference - Chapter 9 ppsx

26 297 0
ASP.NET AJAX Programmer’s Reference - Chapter 9 ppsx

Đ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

Event Bubbling and Button Client Control This chapter discusses the implementation of the ASP.NET AJAX Button client control and Web pages that use this control. You’ll also learn how to implement custom client controls that bubble their events up to their parent client controls, and how to implement custom client controls that catch the events that their child controls bubble up. CommandEventArgs As you’ll see later in this chapter, the Button client control raises an event named command when the user clicks the button. The ASP.NET AJAX CommandEventArgs class is the event data class for the command event, as defined in Listing 9-1 . Listing 9-1: The CommandEventArgs Class Sys.Preview.UI.CommandEventArgs = function Sys$Preview$UI$CommandEventArgs(commandName, argument) { Sys.Preview.UI.CommandEventArgs.initializeBase(this); this._commandName = commandName; this._argument = argument; } function Sys$Preview$UI$CommandEventArgs$get_argument() { return this._argument; } function Sys$Preview$UI$CommandEventArgs$get_commandName() { return this._commandName; } (continued) c09.indd 323c09.indd 323 8/21/07 1:02:52 AM8/21/07 1:02:52 AM Chapter 9: Event Bubbling and Button Client Control 324 Listing 9-1 (continued) Sys.Preview.UI.CommandEventArgs.prototype = { get_argument: Sys$Preview$UI$CommandEventArgs$get_argument, get_commandName: Sys$Preview$UI$CommandEventArgs$get_commandName } Sys.Preview.UI.CommandEventArgs.descriptor = { properties: [ {name: ‘argument’, type: String, readOnly: true}, {name: ‘commandName’, type: String, readOnly: true} ] } Sys.Preview.UI.CommandEventArgs.registerClass(‘Sys.Preview.UI.CommandEventArgs’, Sys.EventArgs); The CommandEventArgs class exposes two read-only properties of type string named commandName and argument . The constructor of this class takes two string parameters and assigns them to these two properties: Sys.Preview.UI.CommandEventArgs = function Sys$Preview$UI$CommandEventArgs(commandName, argument) { Sys.Preview.UI.CommandEventArgs.initializeBase(this); this._commandName = commandName; this._argument = argument; } The constructor of this class is the only way to set the values of the commandName and argument properties. The CommandEventArgs class comes with two methods named get_commandName and get_argument that respectively return the values of the commandName and argument properties of the CommandEventArgs . The get_commandName and get_argument methods are defined on the prototype property of the CommandEventArgs class. As such, they are considered instance methods and must be invoked on a class instance. The CommandEventArgs class, like any other ASP.NET AJAX class, exposes a property named descriptor that describes the members of the class. An object literal with a single name/value pair is assigned to the prototype property. This name/value pair describes the commandName and argument properties of the CommandEventArgs class. Every ASP.NET AJAX event data class must directly or indirectly inherit from the EventArgs base class. The CommandEventArgs class is no exception: Sys.Preview.UI.CommandEventArgs.registerClass(‘Sys.Preview.UI.CommandEventArgs’, Sys.EventArgs); c09.indd 324c09.indd 324 8/21/07 1:02:54 AM8/21/07 1:02:54 AM Chapter 9: Event Bubbling and Button Client Control 325 Button Client Control The ASP.NET Button server control exposes the following important features: ❑ An event named Command : When the end user clicks a Button server control, the control raises two events, Click and Command . The event data class associated with the Command event is an ASP.NET class named CommandEventArgs . When the Button server control invokes an event handler registered for its Command event, it passes an instance of the CommandEventArgs event data class into it. ❑ A property named CommandName : The Button server control assigns the value of its Command- Name property to the CommandName property of the CommandEventArgs object that it passes into the event handlers registered for its Command event. ❑ A property named CommandArgument : The Button server control optionally assigns the value of its CommandArgument property to the CommandArgument property of the CommandEventArgs object that it passes into the event handlers registered for its Command event. The ASP.NET AJAX Button client control emulates the ASP.NET Button server control to offer these three features on the client side, as discussed in the following sections. Constructor As you can see in Listing 9-2 , the constructor of the Button client control takes a single argument that references the DOM element that the control represents. The constructor calls the initializeBase method to invoke the constructor of its base class, passing in the reference to the DOM element. The Button client control is then registered as the subclass of the Control base class. Listing 9-2: The Constructor of the Button Client Control Sys.Preview.UI.Button = function Sys$Preview$UI$Button(associatedElement) { Sys.Preview.UI.Button.initializeBase(this, [associatedElement]); } Sys.Preview.UI.Button.registerClass(‘Sys.Preview.UI.Button’, Sys.UI.Control) prototype As Listing 9-3 shows, the Button client control exposes nine instance methods. They are instance meth- ods because they’re directly defined on the prototype property of the class. As such, you must invoke these methods on a class instance. c09.indd 325c09.indd 325 8/21/07 1:02:55 AM8/21/07 1:02:55 AM Chapter 9: Event Bubbling and Button Client Control 326 Listing 9-3: The prototype Property of the Button Client Control Sys.Preview.UI.Button.prototype = { _command: null, _arg: null, _clickHandler: null, get_argument: Sys$Preview$UI$Button$get_argument, set_argument: Sys$Preview$UI$Button$set_argument, get_command: Sys$Preview$UI$Button$get_command, set_command: Sys$Preview$UI$Button$set_command, initialize: Sys$Preview$UI$Button$initialize, dispose: Sys$Preview$UI$Button$dispose, add_click: Sys$Preview$UI$Button$add_click, remove_click: Sys$Preview$UI$Button$remove_click, _onClick: Sys$Preview$UI$Button$_onClick } argument The Button client control exposes a property named argument , which emulates the CommandArgument property of the Button server control. As Listing 9-4 shows, the get_argument and set_argument methods of the Button client control emulate the getter and setter of the Button server control’s CommandArgument property. Note that the set_argument method calls the raisePropertyChanged method to raise the propertyChanged event. The Button client control inherits this method from its base class. Listing 9-4: The get_argument and set_argument Methods of the Button Client Control function Sys$Preview$UI$Button$get_argument() { return this._arg; } function Sys$Preview$UI$Button$set_argument(value) { if (this._arg !== value) { this._arg = value; this.raisePropertyChanged(‘argument’); } } command As Listing 9-5 shows, the Button client control exposes a property named command and two methods named get_command and set_command that emulate the CommandName property of the Button server control and its associated getter and setter methods. Again, note that the set_command method invokes c09.indd 326c09.indd 326 8/21/07 1:02:55 AM8/21/07 1:02:55 AM Chapter 9: Event Bubbling and Button Client Control 327 the raisePropertyChanged method to raise the propertyChanged event and, consequently, to invoke all the event handlers registered for this event. Listing 9-5: The get_command and set_command Methods of the Button Client Control function Sys$Preview$UI$Button$get_command() { return this._command; } function Sys$Preview$UI$Button$set_command(value) { if (this._command !== value) { this._command = value; this.raisePropertyChanged(‘command’); } } initialize The Button client control overrides the initialize method that it inherits from its base class, as shown in Listing 9-6 . Listing 9-6: The initialize Method of the Button Client Control function Sys$Preview$UI$Button$initialize() { Sys.Preview.UI.Button.callBaseMethod(this, ‘initialize’); this._clickHandler = Function.createDelegate(this, this._onClick); $addHandler(this.get_element(), “click”, this._clickHandler); } The Button client control’s implementation of this method follows the same implementation pattern as the initialize method of the HyperLink client control discussed in the previous chapter. First, it calls the callBaseMethod method to invoke the initialize method of its base class. Every time you implement a client component that overrides the initialize method, your component’s implementa- tion must always call the callBaseMethod method to invoke the initialize method of its base class to allow the base class to initialize itself: Sys.Preview.UI.Button.callBaseMethod(this, ‘initialize’); Next, the initialize method of the Button client control calls the createDelegate method on the Function class to create a delegate that represents the _onClick method of the Button control: this._clickHandler = Function.createDelegate(this, this._onClick); Finally, it calls the addHandler static method on the DomEvent class to register this delegate as an event handler for the click event of the DOM element that the Button client control represents. This means that when the end user clicks the DOM element and raises its click event, it automatically invokes this delegate, which in turn invokes the method that it represents — the _onClick method. c09.indd 327c09.indd 327 8/21/07 1:02:55 AM8/21/07 1:02:55 AM Chapter 9: Event Bubbling and Button Client Control 328 add_click Following the same implementation pattern as the HyperLink client control, the Button client control exposes two methods named add_click and remove_click that allow you to add a specified handler to and remove a specified handler from the list of handlers registered for the click event of the Button client control, as shown in Listing 9-7 . Listing 9-7: The add_click Method of the Button Client Control function Sys$Preview$UI$Button$add_click(handler) { this.get_events().addHandler(“click”, handler); } function Sys$Preview$UI$Button$remove_click(handler) { this.get_events().removeHandler(“click”, handler); } _ on Click One of the great things about the ASP.NET Button server control is that it bubbles its Command event up to its parent server controls. This plays a significant role in composite controls such as GridView and DetailsView . Thanks to event bubbling, these composite controls can catch the events raised by their child controls, such as a Button server control, and expose them as top-level events. This allows these composite controls to hide their child controls from their clients and consequently act as a single entity. The _onClick method of the Button client control emulates the same feature in client-side program- ming, as shown in Listing 9-8 . Listing 9-8: The _ on Click Method of the Button Client Control function Sys$Preview$UI$Button$_onClick() { var handler = this.get_events().getHandler(“click”); if (handler) handler(this, Sys.EventArgs.Empty); if (this._command) { var e = new Sys.Preview.UI.CommandEventArgs(this._command, this._arg); this.raiseBubbleEvent(this, e); } } This method first calls the get_events method to return a reference to the EventHandlerList that contains all the event handlers registered for the events that the Button client control exposes. The Button client control inherits the get_events method from its base class. Next, the _onClick method calls the getHandler method on the EventHandlerList to return a JavaScript function whose invoca- tion automatically invokes all the event handlers registered for the click event of the Button control: c09.indd 328c09.indd 328 8/21/07 1:02:56 AM8/21/07 1:02:56 AM Chapter 9: Event Bubbling and Button Client Control 329 var handler = this.get_events().getHandler(“click”); Next, the _onClick method calls this JavaScript function to invoke all the event handlers registered for the click event: handler(this, Sys.EventArgs.Empty); So far, there was nothing special about the _onClick method. What makes the _onClick method of the Button client control very different from the _onClick method of client controls such as the HyperLink control is that the _onClick method creates an instance of the CommandEventArgs event data class (discussed in the previous section), passing in the values of the command and argument properties of the Button client control: var e = new Sys.Preview.UI.CommandEventArgs(this._command, this._arg); Finally, the _onClick method calls the raiseBubbleEvent method, passing in the CommandEventArgs event data object to bubble the Button control’s command event up to its parent client control: this.raiseBubbleEvent(this, e); Keep in mind that every client control inherits the raiseBubbleEvent method from the Control class. This method provides you with a very nice mechanism to bubble the events of your custom controls to their parent controls to allow the event handlers of the parent controls to handle these events. This enables the parent of a child control to catch the events raised by its child controls and expose them as its own events. This way, the clients of the parent control do not have to deal with the child controls. Instead, they register their event handlers for the events that the parent control exposes. You’ll see an example of this later. dispose As you can see in Listing 9-9 , the Button client control overrides the dispose method of its base class to remove all the event handlers registered for its click event. Note that the Button control’s implementa- tion of this method calls the callBaseMethod method to invoke the dispose method of its base class to allow its base class to do its final cleanup before it is disposed of. Your custom client control’s implemen- tation of the dispose method must always invoke the dispose method of its base class. Listing 9-9: The dispose Method of the Button Client Control function Sys$Preview$UI$Button$dispose() { if (this._clickHandler) $removeHandler(this.get_element(), “click”, this._clickHandler); Sys.Preview.UI.Button.callBaseMethod(this, ‘dispose’); } c09.indd 329c09.indd 329 8/21/07 1:02:56 AM8/21/07 1:02:56 AM Chapter 9: Event Bubbling and Button Client Control 330 descriptor The Button client control, like any ASP.NET AJAX client class, exposes a property named descriptor that describes the members of the Button control. The value of this property is always an object literal. As Listing 9-10 shows, this object contains two name/value pairs, where the first name/value pair describes the properties of the Button control, and the second name/value pair describes the events that the control exposes. The Button control exposes the command and argument properties and the click event. Listing 9-10: The descriptor Property of the Button Client Control Sys.Preview.UI.Button.descriptor = { properties: [ { name: ‘command’, type: String }, { name: ‘argument’, type: String } ], events: [ { name: ‘click’ } ] } Using Button Client Control This section uses a couple of examples to show you the significance of the Button client control’s event-bubbling capability. Event bubbling involves two important methods of the Control base class: onBubbleEvent and raiseBubbleEvent . It is the responsibility of a child client control to invoke the raiseBubbleEvent method to bubble its events to its parent client controls. It is the responsibility of the parent client control to override the onBubbleEvent method to catch and to optionally handle the event bubbled up by its child client control. Catching a Bubbled Event The _onClick method of the Button client control calls the raiseBubbleEvent method to bubble its command event up to its parent client controls. The first example shows you a parent client control named GridView that overrides the onBubbleEvent method to catch the command event that its child Button client controls bubble up. Listing 9-11 presents the GridView.js JavaScript file that contains the implementation of the GridView client control. Listing 9-11: The GridView.js JavaScript File Containing the GridView Client Control Implementation Type.registerNamespace(“CustomComponents”); CustomComponents.GridView = function CustomComponents$GridView(associatedElement) { CustomComponents.GridView.initializeBase(this, [associatedElement]); } function CustomComponents$GridView$onBubbleEvent(source, args) { c09.indd 330c09.indd 330 8/21/07 1:02:56 AM8/21/07 1:02:56 AM Chapter 9: Event Bubbling and Button Client Control 331 var handled = false; if (args instanceof Sys.Preview.UI.CommandEventArgs) { switch (args.get_commandName()) { case “Select”: alert(args.get_argument() + “ is selected!”); handled = true; break; case “Delete”: alert(args.get_argument() + “ is deleted!”); handled = true; break; } } return handled; } CustomComponents.GridView.prototype = { onBubbleEvent : CustomComponents$GridView$onBubbleEvent } CustomComponents.GridView.registerClass(“CustomComponents.GridView”, Sys.UI.Control); if(typeof(Sys)!==’undefined’) Sys.Application.notifyScriptLoaded(); As you can see, the GridView client control exposes a constructor and a method named onBubbleEvent that override the onBubbleEvent method of the Control base class. Constructor Listing 9-12 shows the constructor of the GridView client control. Listing 9-12: The Constructor of the GridView Client Control CustomComponents.GridView = function CustomComponents$GridView(associatedElement) { CustomComponents.GridView.initializeBase(this, [associatedElement]); } CustomComponents.GridView.registerClass(“CustomComponents.GridView”, Sys.UI.Control); As with any other ASP.NET AJAX client control, this constructor takes an argument that references the DOM element that the control represents. It then calls the initializeBase method to invoke the constructor of its base class, passing in the reference to the DOM element. At the end of this listing, the GridView client control is registered as the subclass of the Control base class: CustomComponents.GridView.registerClass(“CustomComponents.GridView”, Sys.UI.Control); c09.indd 331c09.indd 331 8/21/07 1:02:57 AM8/21/07 1:02:57 AM Chapter 9: Event Bubbling and Button Client Control 332 on BubbleEvent The GridView client control overrides the onBubbleEvent method of its Control base class, as shown in Listing 9-13 . Pay close attention to the implementation pattern used to implement the onBubbleEvent method, because the same pattern is used to implement the onBubbleEvent method of all parent client controls that need to catch the events raised by their child client controls. Listing 9-13: The on BubbleEvent Method of the GridView Client Control function CustomComponents$GridView$onBubbleEvent(source, args) { var handled = false; if (args instanceof Sys.Preview.UI.CommandEventArgs) { switch (args.get_commandName()) { case “Select”: alert(args.get_argument() + “ is selected!”); handled = true; break; case “Delete”: alert(args.get_argument() + “ is deleted!”); handled = true; break; } } return handled; } As shown in this listing, you take the following steps to implement the onBubbleEvent method of a parent client control: 1. Declare a local variable named handled and initialize its value to false : var handled = false; 2. Use the instanceof operator to determine whether the event is of the type that the parent client control handles. In this case, the GridView client control handles only command events: if (args instanceof Sys.Preview.UI.CommandEventArgs) 3. Call the get_commandName method on the second parameter passed into the onBubbleEvent method to access the command name: var commandName = args.get_commandName(); 4. Use a switch statement that contains one branch for each command name that the parent client control handles. In this case the GridView client control handles only the Select and Delete commands. 5. Handle the event within each branch and set the value of the handled variable to true . The logic that handles the event can call the get_argument method on the second parameter passed into the onBubbleEvent method to access the command argument. In this case, the c09.indd 332c09.indd 332 8/21/07 1:02:57 AM8/21/07 1:02:57 AM [...]... event (see Figure 9- 3 ) Figure 9- 3 345 c 09. indd 345 8/21/07 1:03:04 AM Chapter 9: Event Bubbling and Button Client Control Listing 9- 2 6 shows a page that uses the new version of the GridView client control Listing 9- 2 6: A Page that Uses the GridView Control ... onBubbleEvent method references the Button client control that raised the command event, and the second parameter of the method references the CommandEventArgs event data object that the _onClick 3 39 c 09. indd 3 39 8/21/07 1:03:02 AM Chapter 9: Event Bubbling and Button Client Control method of the Button client control passed into the raiseBubbleEvent method (shown previously in Listing 9- 8 ) Listing 9- 1 8: The onBubbleEvent... Listing 9- 1 4 contains a Web page that demonstrates the GridView and Button client controls’ eventbubbling capabilities Figure 9- 1 shows what you’ll see when you access this page Listing 9- 1 4: A Page Showing the GridView and Button Client Controls’ Event-Bubbling Capabilities ... Listing 9- 2 1 shows the constructor of the GridViewCommandEventArgs event data class This constructor takes three parameters The first parameter references the GridViewRow client control that bubbles the event up to the GridView control (shown previously in Listing 9- 1 8) The second parameter references the Button child client control that raised the original command event (shown previously in Listing 9- 8 )... read-only 343 c 09. indd 343 8/21/07 1:03:03 AM Chapter 9: Event Bubbling and Button Client Control Listing 9- 2 4: The descriptor Property of the GridViewCommandEventArgs Class CustomComponents.GridViewCommandEventArgs.descriptor = { properties: [{name:’commandSource’, type:Sys.Preview.UI.Control, readOnly:true}, {name : ‘row’, type : CustomComponents.GridViewRow, readOnly: true}] } GridView Listing 9- 2 5... control 338 c 09. indd 338 8/21/07 1:03:01 AM Chapter 9: Event Bubbling and Button Client Control Constructor Listing 9- 1 6 shows the constructor of the GridViewRow client control This constructor takes an argument that references the table row DOM element the control represents At the end of the listing, the GridViewRow class is registered as the subclass of the Control base class Listing 9- 1 6: The Constructor... 346 c 09. indd 346 8/21/07 1:03:04 AM Chapter 9: Event Bubbling and Button Client Control 336 c 09. indd 336 8/21/07 1:03:01 AM Chapter 9: Event Bubbling and Button Client Control Run the page and click the Delete button that deletes the second row This should pop up the message shown in Figure 9- 2 This message contains the... the original command event Listing 9- 2 2: The get_commandSource Method of the GridViewCommandEventArgs Class function CustomComponents$GridViewCommandEventArgs$get_commandSource() { return this._commandSource; } get_row As you can see in Listing 9- 2 3, the get_row method returns a reference to the GridViewRow client control that raised the GridViewCommand event Listing 9- 2 3: The get_row Method of the GridViewCommandEventArgs... ID=”ScriptManager1” runat=”server”> Product Name Unit . ‘dispose’); } c 09. indd 329c 09. indd 3 29 8/21/07 1:02:56 AM8/21/07 1:02:56 AM Chapter 9: Event Bubbling and Button Client Control 330 descriptor The Button client control, like any ASP. NET AJAX client. Listing 9- 1 4 contains a Web page that demonstrates the GridView and Button client controls’ event- bubbling capabilities. Figure 9- 1 shows what you’ll see when you access this page. Listing 9- 1 4:. GridViewRow client control. c 09. indd 338c 09. indd 338 8/21/07 1:03:01 AM8/21/07 1:03:01 AM Chapter 9: Event Bubbling and Button Client Control 3 39 Constructor Listing 9- 1 6 shows the constructor

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

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

Tài liệu liên quan