Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 57 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
57
Dung lượng
0,98 MB
Nội dung
366 CHAPTER 10 Developing with the Ajax Control Toolkit the animation classes. The following example will give you the opportunity to experiment directly with the JSON syntax for creating animations. In this section, we’ll return on the PhotoGallery control built in section 8.4.5. So far, you’ve created a client control to browse a set of images stored in the web- site. Your next goal is to enhance the control by adding an animated transition between the images. The transition you’ll build isn’t complex, but it’s effective, as shown in figure 10.18. While the next image is being loaded, you partially fade-out the current image; then, you resize it until it reaches the width and height of the next image to display. Finally, the new image fades in and replaces the old image. Let’s start by opening the PhotoGallery.js file that contains the code for the Pho- toGallery control. You have to modify the code so that when the next image is loaded, a new method named _playTransition is called. This method is respon- sible for playing the animated transition and then calling the _displayImage method as soon as the transition is completed. First, you must rewrite the _onImage- ElementLoaded method, declared in the PhotoGallery’s prototype, as follows: _onImageElementLoaded : function() { this._playTransition(); } Figure 10.18 Example of an animated transition applied to the PhotoGallery control. The animations that make up the transition are defined through JSON objects. Animations 367 Then, you must add a method called _playTransition to the constructor’s proto- type. The code for the _playTransition method is shown in listing 10.14. _playTransition : function() { var currentImageSize = {height: this._imageElement.height, width: this._imageElement.width}; var nextImageSize = {height: this._imgPreload.height, width: this._imgPreload.width}; var fadeIn = AjaxControlToolkit.Animation.createAnimation( { "AnimationName": "FadeIn", "AnimationTarget": this._imageElement.id, "Duration": 0.3, "MinimumOpacity": 0.2, "MaximumOpacity": 1 } ); var sequence = AjaxControlToolkit.Animation.createAnimation( { "AnimationName": "Sequence", "AnimationTarget": this._imageElement.id, "AnimationChildren": [ { "AnimationName": "FadeOut", "Duration": 0.3, "MaximumOpacity": 1, "MinimumOpacity": 0.2 }, { "AnimationName": "Resize", "Height": nextImageSize.height, "Width": currentImageSize.width }, { "AnimationName": "Resize", "Height": nextImageSize.height, "Width": nextImageSize.width } ] } ); Listing 10.14 Code for the _playTransition method Fade-in animation B Sequence animation C 368 CHAPTER 10 Developing with the Ajax Control Toolkit sequence.add_ended(Function.createDelegate(this, onSequenceEnded)); sequence.play(); function onSequenceEnded() { this._displayImage(); fadeIn.play(); } } The first thing you do in the body of the method is save the height and width of the currently displayed image and the next one in the list. You need these dimen- sions in order to set up the animation that resizes the current image to the size of the next one. The first animation you create is a fade-in B , stored in the fadeIn variable. The animation is created with a call to the AjaxControlToolkit.Animation.create- Animation method. This method accepts an object literal (a JSON object) and instantiates the animations defined in the object. In the JSON object, the value of the AnimationName attribute is the FadeIn string, which corresponds to a fade-in animation. You follow the same rule used in the XML description. The name of an animation is obtained by removing the Animation suffix from the name of the class. The second attribute, AnimationTarget , specifies which element to animate. In this case, it’s the img element that displays the current image. The third attribute, Duration , is the duration of the animation; the last two attributes define the values of the maximum and minimum opacity. The fade-in effect is obtained by animating the opacity value from 0.2 to 1 . You use the same technique to create the sequence animation C that com- pletes the transition. In this case, the AnimationChildren attribute holds an array with the child animations. When the _playTransition method is called, the tran- sition is played in two parts. First, the sequence animation is played. To detect its end, you subscribe to its ended event. The event is handled by a function called onSequenceEnded , declared in the _playTransition method. When the sequence animation ends, the _displayImage method is called to replace the old photo with the new one. Finally, the fade-in animation is played to complete the transi- tion between the two images. The JSON description is compact and leads to highly readable code. The only drawback of this approach is that it’s slower than the imperative syntax because an additional step is required to translate the JSON description into an instance of Subscribe to ended event Play transition Handle ended event Summary 369 the FadeInAnimation class. For this reason, the imperative syntax is preferable when you need maximum performance. In most cases, though, you’ll be able to use the shortest and most readable code. 10.4 Summary In this chapter, we’ve explored the Ajax Control Toolkit, an open-source project started by Microsoft in the early days of ASP.NET AJAX. The Toolkit, which is open to contributions from the community, aims at becoming the biggest free collec- tion of Ajax-enabled controls available. The Toolkit controls are built on top of a custom API that enhances the base functionality provided by the ASP.NET AJAX extensions. The Toolkit API is a meta- data-driven API: Ajax-enabled controls can be authored using attribute-based pro- gramming. All controls created with the Toolkit API provide support for the ASP.NET 2.0 callbacks framework and the Visual Studio Designer. The Ajax Control Toolkit offers also a powerful framework for creating visual effects and animations. We explored the animation classes and explained how to create them in a web page using the AnimationExtender control. You can create animations using XML or JSON syntax, as we demonstrated by adding transition effects to the PhotoGallery control developed in chapter 8. In the next chapter, we’ll look at the XML Script declarative language, which is used to instantiate client components in a page using a declarative syntax. Part 3 ASP.NET AJAX Futures It’s been almost a year since the first official release of ASP.NET AJAX, and plans for the next release are well under way. Currently, features for the next release are available in a separate package called the ASP.NET Futures. In this part of the book, we’ll cover some of these features. Chapter 11 is dedicated to XML Script: a declarative language similar to the ASP.NET markup, which is used to instantiate client components in the page. Chapter 12 covers the drag-and-drop engine, which you can use to drag and drop DOM elements in the page. By the end of these chapters, you’ll be ready to use the main fea- tures that will be included in future releases of ASP.NET AJAX. 373 XML Script In this chapter: ■ XML Script basics ■ Actions ■ Bindings ■ Transformers 374 CHAPTER 11 XML Script XML Script is a declarative language for creating instances of JavaScript objects at runtime, setting their properties, and specifying their behavior, using an XML-like syntax similar to the ASP.NET markup code. In an HTML page, you can separate content (the markup code) from style by embedding the style information in a CSS file. Similarly, in an ASP.NET page, you usually define the page layout using declarative markup code in an ASPX page. Then, you can use a separate code-behind file to specify the behavior of server controls and how they’re wired together, using the classic imperative syntax. XML Script lets you achieve this kind of separation and instantiate JavaScript compo- nents using a declarative script language embedded in a web page. XML Script, like declarative languages, has a number of advantages over the imperative syntax. Building designers for markup is easier than building them for code. Great visual tools, like the Visual Studio Designer, take care of generating markup code for you. If a client can parse declarative markup, you can make server controls render the markup more easily than rendering imperative code. In addition, declarative markup carries semantics. For example, an application that parses a TextBox tag knows that it has to instantiate a text field, but it’s up to the application to decide to instantiate a simple text field rather than a more com- plex auto-complete text box—for example, based on browser capabilities. Finally, declarative code can be more expressive and less verbose than imperative code. Features like bindings help keep the values exposed by object properties synchro- nized, without the need to deal with multiple event handlers. This chapter illustrates these aspects of XML Script, beginning with the basics of the language and moving to advanced features like actions, bindings, and trans- formers. Keep in mind that because they’re part of the ASP.NET Futures package, the features illustrated in this chapter aren’t currently documented or supported by Microsoft. 11.1 XML Script basics Your first goal is learning how to write XML Script code and understanding how it’s turned into instances of client objects at runtime. As we’ll explain in a moment, writing XML Script code is similar to writing ASP.NET declarative code. The main difference is that whereas you use ASP.NET markup to create instances of server-side classes, you use XML Script code to create JavaScript objects. Before you begin using XML Script, you need to enable it in a web page. This turns out to be an easy job, because you have to reference the PreviewScript.js file in the ScriptManager control, as shown in listing 11.1. This file is embedded as a XML Script basics 375 web resource in the Microsoft.Web.Preview assembly, which is shipped with the ASP.NET Futures package. You can find more information on how to install this package in appendix A. <asp:ScriptManager ID="TheScriptManager" runat="server"> <Scripts> <asp:ScriptReference Assembly="Microsoft.Web.Preview" Name="PreviewScript.js" /> </Scripts> </asp:ScriptManager> XML Script code is embedded in script tags with the type attribute set to text/ xml-script . This custom type was defined to distinguish blocks of XML Script code from other script code such as JavaScript. This is what the typical container of an XML Script code block looks like: <script type="text/xml-script"> <! Insert xml-script here > </script> As you can see, XML Script comments have the same syntax as XML comments. You can have multiple blocks of XML Script code in the same page, and they can appear in any order and position. Unlike JavaScript code, though, at the moment XML Script can only appear inline in the page and can’t be saved to separate files. As with any programming language, a “Hello, World!” example is the ideal ice-breaker for introducing basic XML Script features. It’s also a good starting point for learning how XML Script code is structured and to give you confidence with its syntax. 11.1.1 Hello XML Script! This example shows how a block of XML Script code is structured and how you can deal with client objects using declarative code. You’ll see how to handle an event raised by a client component using XML Script code. Normally, you’d accomplish this task by retrieving a reference to the component and writing the necessary JavaScript code to add an event handler. Listing 11.2 shows how to declaratively hook up the init event raised by Sys.Application , the Application object introduced in chapter 2. As promised, the event handler is a JavaScript function that displays a “Hello XML Script!” message onscreen. Listing 11.1 Enabling XML Script in an ASP.NET page [...]... xmlns="http://schemas.microsoft.com/xml-script/2005"> C Binding target B Binding source Bindings Target property 399 D Binding definition E In the code, the binding is declared in a B bindings tag, which is a child node of label Client... example in listing 11.7 The InvokeMethod action invokes a method on a client object that, in turn, calls a method defined in a local Web Service the InvokeMethod action calls the invoke method on the ServiceMethodRequest instance E Note that the instance can be referenced because you assigned it an id Figure 11.5 shows the date string displayed in the label The built -in actions provided by the Microsoft Ajax. .. components expose a property called bindings, which returns an array with all the bindings hosted in the component Later, you’ll see that bindings can also be defined outside of any components NOTE Client components support bindings only in the Futures CTP The Sys Component class as defined in the Microsoft Ajax Library 1.0 doesn’t offer support for bindings at the moment Bindings are supposed to have a source... and data path When you declare a binding in XML Script, the dataContext attribute determines the source component for the binding, assuming the binding direction is set to In The counterpart of the dataContext attribute is the target attribute, which determines the target component for the binding If a binding is declared in a component—as a child node of the bindings element—the component automatically... Figure 11.4 shows the example in listing 11.5 running in Firefox Did you see any JavaScript code in listing 11.5? With actions, you can wrap any kind of JavaScript code and execute it Figure 11.4 The SetProperty action lets you set properties of client components without writing a single line of JavaScript code Actions 389 declaratively The next built -in action we’ll examine is PostBack; it’s used to... Script 11.3.2 Binding direction In the first example, you saw how to define a binding between the text of a text box (the source of the data) and the text of a label (the target of the data) By doing that, you implicitly defined a direction for the binding Every time the source property is modified, the binding is evaluated and the target property is updated; the data involved in the binding goes from... data-source information from the parent control We’ll present an example of declarative data binding in chapter 13 A binding can also be declared outside of any components To declare a standalone binding, you have to explicitly set the target attribute For example, you can move the binding defined in listing 11.12 outside the label and declare it under the components node, as shown in listing 11.13 Listing... target of the binding This is what happens, for example, in listing 11.12, where you declare the binding in the label element NOTE Data context lets child elements inherit from their parent elements information about the data source used for binding, as well as other characteristics of the binding such as the path If you bind the parent element to a data source, the child elements automatically inherit the... display it in the label We’ll introduce bindings in section 12.3 For now, it’s enough to say that a binding can be used to synchronize the value exposed by two properties In this case, you’re synchronizing the result property with the label’s text property As soon as the result property is set, the same happens with the text property The InvokeMethod action E, which is the action you’re interested in, is... methodName="GetTimeAsString"> Actions 391 completed event D E Call invoke . code) from style by embedding the style information in a CSS file. Similarly, in an ASP. NET page, you usually define the page layout using declarative markup code in an ASPX page. Then, you can. runtime. As we’ll explain in a moment, writing XML Script code is similar to writing ASP. NET declarative code. The main difference is that whereas you use ASP. NET markup to create instances of server-side. developed in chapter 8. In the next chapter, we’ll look at the XML Script declarative language, which is used to instantiate client components in a page using a declarative syntax. Part 3 ASP. NET AJAX