Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 53 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
53
Dung lượng
345,85 KB
Nội dung
Variables and Properties | 71 You can access specific elements of the array using array access notation. The follow- ing example retrieves the first element from the array (ActionScript arrays are 0- indexed) and displays it in the console (again, if you are debugging the application): trace(book[0]); You can also assign values to elements using array access notation, as follows: book[2] = "Web Services Essentials"; Arrays are objects in ActionScript, and they have methods and properties like most objects. It’s beyond the scope of this book to delve into the Array API in depth. How- ever, of the Array API, the length property and push( ) method are the most com- monly used. The length property returns the number of elements in the array, and it is commonly used with a for statement to loop through all the elements of an array. The push( ) method allows you to append elements to an array. ActionScript arrays are not strongly typed. That means you can store any sort of data in an array, even mixed types. Theoretically, you could store numbers, strings, dates, and even other arrays in an array. ActionScript does not have any formal hashmaps or similar types. ActionScript does have an Object type, which is the most basic of all object types. Unlike the majority of ActionScript classes the Object class is dynamic, which means you can add arbi- trary properties to Object instances. Although it is generally better to write data model classes than to store data in Object instances using arbitrary properties, there are cases when it is useful to use an Object instance as a hashmap/associative array. The following example creates an Object instance and assigns several keys and values: var authorsByBook:Object = new Object( ); authorsByBook["Programming Flex 2"] = "Chafic Kazoun,Joey Lott"; authorsByBook["ActionScript 3.0 Cookbook"] = "Joey Lott,Keith Peters,Darron Schall"; Objects Objects are composites of state and functionality that you can use as elements within ActionScript code. There are potentially an infinite range of object types, including those from the built-in Flash Player types to Flex framework types to custom types. An object is an instance of a class, which is a blueprint of sorts. Although there are other mechanisms for creating objects, the most common is to use a new statement with a constructor. The constructor for a class is a special function that shares the same name as the class. For example, the constructor for the Array class is called Array. Like any other functions a constructor may or may not expect parameters. The only way to know whether a particular constructor expects parameters is to con- sult the API documentation. However, unlike most functions, a constructor must be used as part of a new statement, and it always creates a new instance of the class. The following example creates a new array using a new statement: var books:Array = new Array( ); 72 | Chapter 4: ActionScript Objects may have properties and methods depending on the type. Properties are essentially variables associated with an object, and methods are essentially functions associated with the object. You can reference properties and methods of an object in ActionScript using dot-syntax. Dot-syntax uses a dot between the name of the object and the property of the method. The following example uses dot-syntax to call the push( ) method of the array object (the push( ) method appends the value as an array element): books.push("Programming Flex 2"); The next example uses dot-syntax to reference the length property of the array object: trace(books.length); Inheritance You can create new classes (called subclasses) that inherit from existing classes (called superclasses). You achieve this using the extends keyword when declaring the class. The extends keyword should follow the class name and be followed by the class from which you want to inherit. The following defines class B, so it inherits from a fictional class, A: package com.example { import com.example.A; public class B extends A { } } ActionScript 3.0 allows a class to inherit from just one superclass. The subclass inherits the entire implementation of the superclass, but it can access only properties and methods declared as public or protected. Properties that are declared as private and methods are never accessible outside a class—not even to subclasses. Classes in the same package can access properties declared as internal. Consider the class A and class B example, if A is defined as follows: package com.example { public class A { private var _one:String; protected var _two:String; public function A( ) { initialize( ); } private function initialize( ):void { _one = "one"; _two = "two"; } public function run( ):void { trace("A"); } } } Interfaces | 73 In this example, B (which is defined as a subclass of A) can access _two and run( ), but it cannot access _one or initialize( ). If a subclass wants to create its own implementation for a method that it inherits from a superclass, it can do so by overriding it. Normally, a subclass blindly inherits all of the superclass implementation. However, when you override a method, you tell the subclass that it should disregard the inherited implementation and use the over- ridden implementation instead. To override a method, you must use the override keyword in the method declaration; the following overrides the run( ) method: package com.example { import com.example.A; public class B extends A { override public function run( ):void { trace("B"); } } } When a subclass overrides a superclass method, the subclass method’s signature must be identical to the superclass method’s signature, i.e., the parameters, return type, and access modifier must be the same. Interfaces ActionScript 3.0 also allows you to define interfaces. Interfaces allow you to separate the interface from the implementation, which enables greater application flexibility. Much of what you learned about declaring classes applies to declaring interfaces as well. In fact, it’s easier to list the differences: • Interfaces use the interface keyword rather than the class keyword. • Interfaces cannot declare properties. • Interface methods declare the method signature but not the implementation. • Interfaces declare only the public interface for implementing classes, and there- fore method signature declarations do not allow for modifiers. By convention, interface names start with an uppercase I. The following is an exam- ple of an interface: package com.example { public interface IExample { function a( ):String; function b(one:String, two:uint):void; } } In the preceding example, interface says that any implementing class must declare methods a( ) and b( ) using the specified signatures. 74 | Chapter 4: ActionScript You can declare a class so that it implements an interface using the implements key- word, following the class name or following the superclass name if the class extends a superclass. The following example implements IExample: package com.example { import com.example.IExample; public class Example implements IExample { public function Example( ) { } public function a( ):String { return "a"; } public function b(one:String, two:uint):void { trace(one + " " + two); } } } When a class implements an interface, the compiler verifies that it implements all the required methods. If it doesn’t, the compiler throws an error. A class can implement methods beyond those specified by an interface, but it must always implement at least those methods. A class can also implement more than one interface with a comma-delimited list of interfaces following the implements keyword. Handling Events ActionScript 3.0 and the Flex framework use events to notify and receive notification when things occur. Events occur in response to the user (for example, the user clicks on something), time (timer events), and asynchronous messaging (such as remote procedure calls). Regardless of the cause of an event, nearly all ActionScript events use the same event model. In MXML (Chapter 3), you saw how to use event handler attributes. In Action- Script, you can handle events by registering listeners. A listener is a function or method that should receive notifications when an event is dispatched. For example, you can register a method to receive a notification when the user clicks a button. You need at least two elements to register a listener: an object that dispatches events, and a function that listens for events. Objects capable of dispatching events either extend the flash.events.EventDispatcher class or implement the flash.events. IEventDispatcher interface. When an object can dispatch events, it has a public addEventListener( ) method that requires at least two parameters; the name of the event for which you want to listen and the function/method that should listen for the event: object.addEventListener("eventName", listenerFunction); In most cases, the event names are stored in constants of the corresponding event type class. For example, the click event name is stored in the MouseEvent.CLICK constant. Handling Events | 75 The listener function must expect one parameter of type mx.events.Event or the rele- vant subclass of Event. For example, if the object dispatches an event of type MouseEvent, the listener should accept a MouseEvent parameter. The event parameter contains information about the event that occurred, including a reference to the object dispatching the event (the target property of the event object) and the object that most recently bubbled (relayed) the event (the currentTarget property). (In many cases, the target and currentTarget properties reference the same object.) The following example adds an event listener using ActionScript, and when the user clicks the button, the listener displays the event object in an alert dialog box: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="initializeHandler(event)"> <mx:Script> <![CDATA[ import mx.controls.Alert; private function initializeHandler(event:Event):void { button.addEventListener(MouseEvent.CLICK, clickHandler); } private function clickHandler(event:MouseEvent):void { Alert.show(event.toString( )); } ]]> </mx:Script> <mx:Button id="button" /> </mx:Application> You can also unregister an event listener using the removeEventListener( ) method. This method requires the same parameters as addEventListener( ). The method unregisters the specified listener function as a listener for the specified event. It is extremely important that you remove event listeners when they are no longer neces- sary. This includes all cases where you want to remove from memory the object lis- tening for the events. Flash Player will not garbage-collect an object if there are any references to it still in memory. That means that even if an object is no longer used anywhere in the application, except for a reference held by an event dispatcher, it will not be garbage-collected. The following example removes the event listener added in the previous example: button.removeEventListener(MouseEvent.CLICK, onClick); 76 | Chapter 4: ActionScript Error Handling ActionScript 3.0 supports runtime error handling. That means that if and when an error occurs, the application can respond to the error in an elegant fashion rather than simply fail to work without any notification to the user. ActionScript 3.0 uses two types of runtime errors: synchronous and asynchronous. Handling Synchronous Errors Synchronous errors occur immediately when trying to execute a statement. You can use try/catch/finally to handle synchronous errors. When you have some code that may throw runtime errors, surround it with a try statement: try { // Code that might throw errors } You must then include one or more catch blocks following a try. If the code in the try block throws an error, the application attempts to match the error to the catch blocks in the order in which they appear. Every catch block must specify the specific type of error that it handles. The application runs the first catch block that it encounters to see if it matches the type of error thrown. All error types are either flash.errors.Error types or subclasses of Error. Therefore, you should try to catch more specific error types first, and more generic types (e.g., Error) later; for example: try { // Code that might throw errors } catch (error:IOError) { // Code in case the specific error occurs } catch (error:Error) { // Code in case a non-specific error occurs } In addition, you can add a finally clause that runs regardless of whether the try statement is successful: try { // Code that might throw errors } catch (error:IOError) { // Code in case the specific error occurs } catch (error:Error) { // Code in case a non-specific error occurs } finally { // Code to run in any case } Error Handling | 77 Most Flash Player and Flex framework classes use asynchronous errors rather than synchronous errors, so the following example may seem impractical, but it does illus- trate the syntax for using try/catch. The browse( ) method for a FileReference object opens a browse dialog box that lets the user select a file from his local filesystem. However, Flash Player can display only one browse dialog box at a time. If you call browse( ) while a browse dialog box is already open, it throws a flash.errors.IOError type of error. If you don’t handle the error, the user receives a notification in a default error dialog box: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="initializeHandler(event)"> <mx:Script> <![CDATA[ import flash.net.FileReference; private function initializeHandler(event:Event):void { var file:FileReference = new FileReference( ); file.browse( ); file.browse( ); } ]]> </mx:Script> </mx:Application> The following example rewrites the preceding code using error handling: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="initializeHandler(event)"> <mx:Script> <![CDATA[ import flash.net.FileReference; private function initializeHandler(event:Event):void { var file:FileReference = new FileReference( ); try { file.browse( ); file.browse( ); } catch(error:Error) { errors.text += error + "\n"; } } ]]> </mx:Script> <mx:TextArea id="errors" /> </mx:Application> 78 | Chapter 4: ActionScript Handling Asynchronous Errors Many objects in ActionScript can potentially throw asynchronous errors. Asynchro- nous errors are those that occur in response to network operations. For example, if a requested file is not found, the network operation fails asynchronously, and an asyn- chronous error is thrown. All asynchronous errors are in the form of events, and they use the same event model as standard events. For example, if a URLLoader object attempts to load data outside the Flash Player security sandbox, it dispatches a securityError event. The following example illustrates how to handle error events: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="initializeHandler(event)"> <mx:Script> <![CDATA[ private function initializeHandler(event:Event):void { var loader:URLLoader = new URLLoader( ); // In order to test this you'll need to specify a URL of a file that // exists outside of the security sandbox. loader.load(new URLRequest("data.xml")); loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); } private function securityErrorHandler(event:SecurityErrorEvent):void { errors.text += event + "\n"; } ]]> </mx:Script> <mx:TextArea id="errors" /> </mx:Application> Using XML XML is a standard protocol for transferring, storing, and reading data for a variety of purposes, including application initialization parameters, data sets, and remote pro- cedure calls. Flex applications can work with XML by using Flash Player’s native support. Flash Player 9 supports two mechanisms for working with XML: a legacy XMLDocument class and the new XML class that implements the ECMAScript for XML (E4X) standard. All XML examples in this book use E4X unless otherwise noted. Using XML | 79 Creating XML Objects There are two ways to create XML objects in ActionScript: using XML literals or with the XML constructor. XML literals are useful when you want to define the XML data directly in the code and you know the exact XML data you want to use. The follow- ing example defines an XML literal and assigns it to a variable: var xml:XML = <books> <book> <title>Programming Flex 2</title> <authors> <author first="Chafic" last="Kazoun" /> <author first="Joey" last="Lott" /> </authors> </book> <book> <title>ActionScript 3.0 Cookbook</title> <authors> <author first="Joey" last="Lott" /> <author first="Keith" last="Peters" /> <author first="Darron" last="Schall" /> </authors> </book> </books>; We’ll assume that this is the XML object referenced by the remainder of the XML examples in this chapter. If you aren’t able to define the XML data directly in ActionScript, you can load the data as a string and pass it to the XML constructor. In the following example, loadedXMLData is a variable containing XML data loaded from an external source at runtime: var xml:XML = new XML(loadedXMLData); When you use the XML constructor, any string data you pass to the constructor is parsed into the XML object as XML nodes. By default, Flash Player attempts to inter- pret all string data as XML. That means it interprets whitespace (carriage returns, tabs, etc.) as XML nodes. That can cause unexpected results. Therefore, if the XML string data you pass to an XML constructor contains extra whitespace (for formatting purposes) that you don’t want interpreted as XML nodes, you should first set the static ignoreWhitespace property to true for the XML class, as shown here: XML.ignoreWhitespace = true; var xml:XML = new XML(loadedXMLData); 80 | Chapter 4: ActionScript Reading XML Data Once you have an XML object, you can read from the object. There are two basic ways in which you can read the data: by traversing the document object model (DOM) or by accessing the data using E4X syntax. The two techniques are not exclu- sive of one another: you can use them in conjunction with one another. In each case that outputs an XML node, the following examples use the toXMLString( ) method to format the XML node as a string. When viewing the XML data in light of the DOM, treat it simply as a hierarchical structure of data consisting of parent and child nodes. When looking at the DOM, focus primarily on the structure rather than the content. You can retrieve all the con- tent from an XML object by treating it in this manner, but you access the data by structure by stepping into the XML one node at a time. The XML class defines a host of methods for retrieving DOM structure information, including the following: children( ) The children( ) method returns an XMLList object with all the child nodes of an XML object. The XMLList class implements a very similar interface to that of XML, and all of the methods discussed in this section apply to both XML and XMLList. An XMLList object is essentially an array of XML or XMLList objects. You can even retrieve elements from an XMLList object using array access notation. For exam- ple, the following code retrieves the book nodes as an XMLList. It then displays the first element from that list: var bookNodes:XMLList = xml.children( ); trace(bookNodes[0].toXMLString( )); length( ) The length( ) method returns the number of elements. For XML objects, this always returns 1. For XMLList objects, it may return more than 1. The following example illustrates the children( ) and length( ) methods used in conjunction. This example displays the titles of each of the books: var bookNodes:XMLList = xml.children( ); for(var i:uint = 0; i < bookNodes.length( ); i++) { trace(bookNodes[i].children()[0].toXMLString( )); } parent( ) You can retrieve the parent of an XML or XMLList object using the parent( ) method. For example, the following displays the first book node by accessing the title node first, and then it retrieves the parent of that node: trace(xml.children()[0].children()[0].parent().toXMLString( )); [...]... building Flex applications because Flex automatically handles all the bootstrapping and initialization, including creation of the SystemManager object and the default preloader However, there are at least two instances when you’ll want to know this information: when loading a Flex application into another Flex application and when customizing the preloader Loading One Flex Application into Another Flex. .. Framework Fundamentals 5 Much of what Flex does is to simplify application development In order to do that, Flex does a lot behind the scenes In many cases, you don’t need to know about these things in order to build applications with Flex However, as you try to achieve more complex and sophisticated goals using Flex, you’ll likely find that it is important to understand how Flex works at a more fundamental... functionalities and behaviors You’ll learn about the life cycle for Flex applications, differentiating between Flash Player and Flex class libraries, bootstrapping Flex applications, partitioning loaded applications into application domains, and more Understanding the Flex Application Life Cycle Although it’s possible to build some Flex applications without having an understanding of the application... loading Flex applications at runtime Figure 5-1 illustrates the basic application startup event flow SystemManager timeline frame 1 frame 2 Preloader Application Flex framework used by application Figure 5-1 Basic application startup event flow Once the SystemManager instance for a Flex application has advanced to the second frame, it creates an instance of the main application class for the Flex application... With some work, you can create complex systems that use objects to create sophisticated and dynamic applications Summary In this chapter, we discussed the fundamentals of ActionScript 3. 0 ActionScript is the ECMAScript-standard-based programming language used by Flex applications... URLRequest("RuntimeLoadingExample.swf"); var loader:Loader = new Loader( ); loader.load(request, context); You can read more about ApplicationDomain in the Flex documentation and at http://mannu.livejournal.com /3 726 62. html Understanding the Preloader By default, all Flex applications have a preloader with a progress bar that indicates progress as the application loads and initializes This preloader is a lightweight... low-level workings of the Flex framework Although it’s not always necessary to work directly with these aspects of a Flex application, an understanding of these topics can help you when building applications that might require lower-level changes We also discussed the Flex application life cycle, differentiating between the Flex framework and Flash Player API, bootstrapping a Flex application, application... the instructions Therefore, what differentiates Flash and Flex applications is not the content, but how you create that content Flex consists of a compiler that is capable of compiling MXML and ActionScript The entire Flex framework is written in ActionScript and MXML It provides a layer 88 | Chapter 5: Framework Fundamentals of abstraction The Flex framework consists of many thousands of lines of code,... If the class is in a package starting with the letters mx (e.g., mx.controls.Button), it is part of the Flex framework • MXML tags almost always (with few exceptions) correspond to Flex framework classes Bootstrapping Flex Applications Although it would be natural enough to assume that the root of a Flex application is an Application object (because the root tag of the runnable application is an Application... applications that will deliver an optimal user experience As shown in Chapter 1, Flex applications are essentially Flash applications that use the Flex framework (which is written in ActionScript) That means everything in a Flex application can be reconciled to something that is available to Flash applications The root of a Flex application is typically SystemManager, which is a subclass of flash.display.MovieClip, . a Flex applica- tion into another Flex application and when customizing the preloader. Loading One Flex Application into Another Flex Application Loading one Flex application into another Flex. authorsByBook:Object = new Object( ); authorsByBook[" ;Programming Flex 2& quot;] = "Chafic Kazoun,Joey Lott"; authorsByBook["ActionScript 3. 0 Cookbook"] = "Joey Lott,Keith Peters,Darron. literal and assigns it to a variable: var xml:XML = <books> <book> <title> ;Programming Flex 2& lt;/title> <authors> <author first="Chafic" last="Kazoun"