Chapter 2. ActionScript 3, XML, and E4X

If you don’t know a decent amount of ActionScript 3, Flex 4 will always be a mystery. So in this chapter, you’ll learn the basics of ActionScript 3. Once again, we’ll build a series of self-contained workshop sessions. However, to minimize context switching we’ll base them on a similar toy example. These workshop sessions will explain numerous concepts at once, since it’s hard to explain arrays without involving looping, and vice versa. Also, we’ll cover multiple concepts at once out of necessity: there are entire books devoted to learning ActionScript 3—and this is not one of those books. Instead, we’ll explore the basics of ActionScript 3 in five workshop sessions. This obviously will be a very high-level treatment, but you should absorb enough that you can use Flex 4 comfortably even if you’ve never seen ActionScript before.

If you’re an experienced Flex 3 developer who is just reading this book for the Flex 4 stuff, you can safely skip this chapter.

Session 6. Variables, functions, types, and scope

In this workshop session, we’ll begin tackling the basics of ActionScript 3. These include variables, functions, and accessors and mutators (better known as getters and setters). These also include the types and access control namespace (commonly referred to as “scope”) attributes (better known as public, protected, internal, and private) of these variables and functions. As always, you’ll learn by doing. Let’s start by creating a model package and a Task class inside it.

session06/src/model/Task.as

The Task class is in the model package.

Variables are created with declarations like public var name:String; that specify the access control (public), the variable name (name), and the type (String). Access control can be public, protected, internal, or private. (You can also use your own custom access control namespaces—if you’re interested, see the “Packages and namespaces” section of Chapter 4 of Adobe’s Programming ActionScript 3 book for details. Note that this language feature is almost never used when writing typical Flex applications; I’m only mentioning it here for completeness.)

The special type * can be used to indicate any type. You can also skip the type declaration, but doing so produces compiler warnings. Type checking is your friend, so use explicit types when you can.

These variables are examples of both primitives (Boolean, int, uint, Number, and String) and of core classes (such as Date) that don’t need to be imported.

The constructor function is used to initialize the object. Functions can take parameters, which can have default values. If a function parameter has a default value, the actual argument can be omitted. All functions except the constructor function can—and should—have return types.

If something is untyped, it can be anything—even an ostrich.

This public function returns a Date (someDate), which is protected. The return type of a function is specified after the argument list.

This getter returns _aNumber. Note that the function keyword is followed by the get keyword.

This setter sets _aNumber to value. All setter functions return void—that is, nothing. Note that the function keyword is followed by the set keyword. By convention, the parameter to a set function is always called value.

The access control of a variable determines who can access it. The choices are public (any class), protected (the class itself or subclasses), internal (classes in the same package) or private (the class itself). Unlike in Java, protected does not give access to classes in the same package.

We also encountered types in the Task model earlier, such as the String in public var name:String. Type checking is done at both compile time and runtime. Compile-time type checking is disabled when either the type is omitted (which produces a compiler warning in Strict mode) or explicitly left unspecified with the * (which prevents the compiler warning). To avoid type errors at runtime it’s best to do as much compile-time type checking as possible, so it’s a good idea to type your variables. (When I work with Ruby programmers on Flex projects, I don’t even tell them that compile-time type checking is optional!)

There are two kinds of types that we encountered earlier. The primitive types in ActionScript are Boolean (true/false), int (a 32-bit signed integer), uint (a 32-bit unsigned integer), Number (a 64-bit floating point), and String (which stores text). There are also a number of “core classes,” which are Objects but that are imported automatically by the compiler so you don’t need to add import statements yourself. The core classes include Object (everything that isn’t primitive is an Object), Array, Date, Error (for exceptions), Function (which are called methods when they’re part of objects), RegExp, XML, and XMLList. As we’ll see later in this chapter, ActionScript 3 features outstanding XML support using something called E4X.

Now that we’ve created the Task class, let’s use it. We’ll build a top-level Flex app called Tester to do just that.

session06/src/Tester.mxml

Our Task class isn’t a “core class,” so it needs to be imported using import.

Create a new Task object, passing the name into the constructor.

We assign the text property of the outputTA TextArea with a String showing the state of the Task. For non-public variables we use the functions. Note that the aNumber getter is accessed using the same property syntax as variables like name and something. (We will cover TextArea in greater detail in subsequent chapters; for now, just think of it as a big rectangular component that can edit text.)

Since something is untyped, it can go from being the String “Ostrich” to the number 5.

Assign 3.14 to _aNumber via the aNumber setter. Note that this property assignment looks the same as the assignment to the something variable of the Task object.

Let’s see what this does. Run the Tester app; you’ll see a screen like the following—except your Date will almost certainly be different and your random number will (almost!) certainly be different.

That’s it! Now that we’ve seen the basics of variables, functions, access control, and types, we can move on to the next workshop session where we play with Objects, Arrays, and control flow (branching and looping).

Key points

  • Variables are declared with var.
  • Functions are declared with function.
  • All functions can take arguments, and all functions except the constructor function can return values.
  • If a non-constructor function doesn’t return anything, specify that it returns nothing by using the void keyword.
  • Variables and functions can (and should) have a public, private, protected, or internal access level. (I say should since by default you’ll get a warning unless you specify the access level. Just do it.)
  • Getters and setters can be used to provide property-style access to private variables that looks indistinguishable to a variable from the outside world but that can do other interesting things.

Session 7. Objects, Arrays, Collections, and Looping

In this workshop session, we’ll learn more ActionScript. We take a fast-paced tour of the Object class, anonymous objects, Array and ArrayCollection, branching (if/else, switch, and the ternary operator) and looping (for, for each, for in, while, do while). The assumption here is that you’ve seen arrays, if statements, and loops before—just not in ActionScript. Almost any popular programming language has them, and they’re just as unsurprising here as elsewhere. (If you need a more thorough treatment of ActionScript 3 than this chapter provides, I highly recommend the Programming ActionScript 3 PDF that comes with the Flex 3 documentation at http://livedocs.adobe.com/flex/3/progAS_flex3.pdf. Once it’s updated for Flex 4, presumably later in 2009, there will be a newer URL. Again, Google is your friend here.) Furthermore, we’ll do all this in one function inside one carefully constructed code example, shown next.

session07/src/Tester.mxml

Objects can be constructed with either the new Object() syntax or by creating an anonymous Object using curly braces. Don’t confuse this use of curly braces with data binding: both use curly braces ({}), but the compiler figures out what you are doing based on context. Similarly, Arrays can be constructed using the new Array() syntax or by using square brackets, [].

Arrays have a join function that’s useful for producing Strings without the need for a tedious loop. Arrays also have a map function, which is useful for functional programming–style code. Note that push adds something to the end of an Array, while unshift adds something to the beginning of an Array.

ActionScript 3 has a standard for loop, as well as while and do while loops, which work the same way they do in every other language. Note the use of the ternary a ? b : c operator. I use int rather than uint as my loop index since that’s the typical convention—while some people may complain that you should use uint since the loop indexes can’t be negative, using int runs slightly faster. Also, I’ve never accidentally gotten a negative loop index while looping, so using uint is pedantic.

Flex code often uses an ArrayCollection, which is in the mx.collections package. The ArrayCollection is more suitable for data binding than Array is, and Flex is all about data binding. This example shows that looping over an ArrayCollection is similar to an Array, except the getItemAt(index) method is used instead of the someArray[index] subscript notation. This example also shows the switch/case statement, which is used for multiway branching. Finally, note something very subtle: I used j and not i for my loop index variable, since I had already used a loop index variable i earlier in the function and since variables inside a function are all in the same scope. Yes, you read that correctly: the for loop does not create its own variable scope. (This is fairly atypical among programming languages, so be careful here!)

ActionScript 3 has a for each ... in loop, which iterates over the values in a collection. This example also shows the standard if/else statement.

ActionScript 3 has a for ... in loop, which iterates over the keys in a collection (or in an Object). These keys can be used to get the values, as shown here.

Running this example we, see the following screen.

That’s it!

Key points

  • Objects can be constructed with the new Object() or {key1: value1 , ... } syntax.
  • ActionScript features the ternary operator, if/else, and switch statement, as well as the for, while, and do while loops you use all the time.
  • ActionScript features for ... in and for each ... in loops.
  • Flex often uses ArrayCollections to wrap Arrays and play nicely with data binding. Iterating over these ArrayCollections is straightforward.

Session 8. Interfaces, casting, is, and as

Having explored the basics of objects in ActionScript 3 in the previous two sessions, we’ll now dive deeper in this workshop session and discuss interfaces, casting, and the is and as operators. After this, and our discussion of inheritance in the next workshop session, we’ll have a good handle on the basics of objects in ActionScript.

Briefly, an interface is a contract (that is, a set of methods) that a class must honor if it implements the interface. The advantage of interfaces is that it lets you write more reusable code that’s more abstracted and less coupled to implementation details. If you’re familiar with interfaces from languages such as Java, you’ll be happy to know that they work pretty much the same way in ActionScript 3. (Unfortunately, unlike Java, you can’t add constants to ActionScript 3 interfaces.) Also, ActionScript 3 interfaces have support for property getters and setters, which is important since otherwise they’d be virtually useless given how property-centric Flex is. (Although, unfortunately, you can’t implement an interface and use a public var in the place of the getters and setters, which would have been a nice shortcut in trivial cases.) Understanding how to use interfaces will let us write more elegant code that’s more flexible and less tied to one specific implementation.

In this session we’ll create an IThing interface, which will be implemented by Task and Project classes. I use an agile project management tool called Pivotal Tracker every day, so I think about Tasks having “story points,” which indicates how much work a Task should take. Since the number of story points in a project is the sum of its Tasks, we can put the points into the IThing interface and show a somewhat meaningful example.

session08/src/model/IThing.as

Property get and set functions can go in an interface.

Normal functions can go in an interface as well.

Note that no access control specifier is needed (or permitted), since all functions in an interface are public.

Next, we create a Task class that implements IThing.

session08/src/model/Task.as

Task implements IThing. Note that the use of underscores for private instance variables is a convention, not a language requirement. For a list of many useful Flex coding conventions see http://opensource.adobe.com/wiki/display/flexsdk/Coding+Conventions.

The static keyword means that it belongs to the class itself; that is, it’s independent of the instances of this class. The const keyword means that it’s a constant, not a variable. (I used multiplication instead of just the result to be more readable. Note that the Date#getTime() method returns a Number, not an int.)

Note that the method signatures match the interface, meaning the class must provide an implementation of the methods defined in the interface.

Next, we create a Project class that also implements IThing.

session08/src/model/Project.as

Project implements IThing.

The getPoints method calculates the points based on the tasks in the project.

Finally, we develop a Tester app that creates some Tasks and Projects and shows how they can be treated as IThings. It also illustrates the use of the is and as keywords.

session08/src/Tester.mxml

We start by creating a couple of Projects and Tasks.

The literal Array syntax can be used to create the argument to the ArrayCollection constructor, which takes an Array.

Note the use of addItemAt to put a project into the ArrayCollection.

We can loop over the ArrayCollection of Tasks and Projects and treat each of them as IThings.

The is operator returns true if the thing is a Task (or a subclass of Task). If it is a Task, we can safely cast the thing to a Task using the Task(thing) syntax. Note that this is Task(thing) not (Task)thing, unlike in some other languages.

The as operator can be used safely where casting might blow up (if the object was the wrong type). If the type doesn’t match, it just returns null. So, we use a null check.

Running this app produces the following output:

Note that Task and Project objects both show their number of points, which is done generically for IThings. However, the Tasks also show when they’re due using code that only executes for Task objects (with the is check), and the Projects show how many Tasks they contain using code that only executes for Project objects (with the as and null checks).

That’s it!

Key points

  • Interfaces can be used to specify a contract that objects must implement, in terms of public functions and getter and setter functions.
  • The is keyword can be used to test whether an object is an instance of a class (which includes a subclass of that class).
  • Casting can be used for explicit type conversion. Be careful, though, since if you cast and get it wrong, your program will explode. Guarding a cast with an is check is a good way to be careful—and is preferable to instanceof, which is an old way of doing this test that we won’t discuss in this book.
  • The as keyword lets you cast safely without an is test, and returns null if the type doesn’t match. Of course, then you need to test for null...

Session 9. Inheritance

In this workshop session, you’ll learn about inheritance. Inheritance is the “is a” kind of reuse, in which one “child” class is a subclass of a “parent” class (or superclass), and has all of its parent’s properties and adds or overrides its own. The Flex framework has an extensive class hierarchy, defined (as all class hierarchies are) by inheritance.

The IThing interface and Tester application are unchanged from session 7. The Tester application is fairly long, so I won’t show it again. To refresh your memory, here’s the IThing interface:

session09/src/model/IThing.as
package model {
public interface IThing {
function get name():String;
function set name(value:String):void;
function getPoints():int;
}
}

Now, one thing you might have noticed in the previous session was that there was duplicate code for setting the name. So, let’s fix that. Let’s create a Thing class that implements the common code for all Things, and that will throw an Error for functionality that must be implemented by subclasses. (If you’re wondering “Why not just make an abstract class?” the simple answer is that abstract classes don’t exist in ActionScript 3. So, this is how you fake it.)

session09/src/model/Thing.as

Thing implements IThing.

Thing has a protected _name variable. When building something you intend to be subclassed, you can use protected instead of private if you want to allow subclasses to have more access to the internals of the parent class. Or, you can take the approach of making the variable private and providing get/set methods, in order to ensure that subclasses access variables the same way as the outside world.

Thing throws an Error if getPoints() isn’t overridden. An Error is the ActionScript 3 version of an exception.

Thing defines the get and set functions for name.

Now we’re going to create Task and Project classes that extend Thing and thus implement IThing by inheritance. You can modify the code from the previous session, or create new code if you’re creating different projects for each session.

session09/src/model/Task.as

Task extends Thing (which implements IThing).

Task has a points variable.

Task overrides the getPoints function from Thing with the override keyword. This keyword is mandatory.

Next, we create a Project class that also extends Thing and thus implements IThing.

session09/src/model/Project.as

The Project class also extends the Thing class.

The Project class also overrides the getPoints function, summing the points of its tasks.

Running the Tester application results in the same output we saw earlier:

That’s it for the “See Spot Run” stuff! In the next section we get to talk about XML, XMLListCollection, and E4X!

Key points

  • Inheritance is a useful way of preventing copy and paste code. (However, the older and more cynical I get, the more I prefer composition.)
  • To subclass a class, use the extends keyword.
  • When overriding a function, use the override keyword.

Session 10. E4X, XML, XMLList, and XMLListCollections

The previous four sessions showed the basics of ActionScript 3, which resemble the basics of any object-oriented programming language. Frankly, you may have been a little bored. Well, after my many years of software development and writing experience, I know the surefire way to cure boredom: XML.

Actually, in all seriousness, the way that Flex and ActionScript 3 support XML is pretty cool. Or, if you don’t think it’s cool, at least admit it’s not as uncool as it is everywhere else!

In this workshop session, you’ll learn how to use XML in Flex. This includes learning the built-in XML and XMLList types, as well as Flex’s XMLListCollection. As a bonus, we’ll learn how to sort collection classes that, like XMLListCollection and ArrayCollection, extend ListCollectionView and implement ICollectionView: this is a Flex book after all.

What we’re going to do is create a new Tester app. This one will be stand-alone. Its entire purpose in life will be to create some XML and then do some stuff to it.

session10/src/Tester.mxml

XMLListCollection, Sort, and SortField are Flex framework classes so they must be imported.

We create literal XML and assign it to a variable of type XML. Yes, this is XML inside a CDATA tag inside XML. Note that ActionScript natively understands XML literals; there is no special syntax required when using XML literal expressions.

You can use E4X (an acronym for ECMAScript 4 XML; ActionScript is based on ECMAScript) to get child nodes by index or by searches on attribute values such as @name=="Proj2".

Getting the children of an XML object gets an XMLList, which can be iterated on with a for each loop.

E4X, attribute, and child element values can be retrieved with dot (.) syntax. For an attribute value, just add the @ prefix.

You can use the hasOwnProperty function to check whether a property (element or attribute) exists.

We construct a new XMLListCollection of all the tasks by getting all the descendant elements of the root node that are named task. Note that this does not include text nodes, XML comments, processing instructions or attributes.

We then create a new Sort object and add a SortField of name (with caseInsensitive set to true with the second parameter to the constructor). This Sort is then assigned to the allTasks collection and then the collection’s refresh() method is called to update the collection to be sorted by the Sort.

Now that the collection is sorted, we can iterate through the sorted collection and output the names.

Run the app; you’ll see the following screen:

Note the nice display of the projects and the tasks they contain, which was produced by the nested loops. Also, note that the XMLListCollection is sorted: “Get a coffee” comes before “Understand E4X,” as it should!

Key points

  • E4X, which stands for ECMAScript for XML, is a great way to handle XML. You’ll never want to touch the DOM or have SAX again.
  • XMLListCollection is a nice, friendly way to work with XMLList, and lets you sort the data using the same approach that can be used with any Flex collection, such as ArrayCollection, that implements ListCollectionView. We will see ArrayCollections and XML used extensively in the book, so don’t worry if this seems a bit like drinking from a firehose. That’s the intent; I want to get back to Flex as fast as possible.
  • XML and XMLList are native types in ActionScript 3 and don’t need to be imported.

What’s next?

What’s next? Simple: we’re going back to Flex!

Well, that’s kind of a misnomer: since all Flex 4 programming is done in ActionScript 3, we never really left: writing MXML typically involves writing nested ActionScript in CDATA tags, and even the MXML itself is all translated behind the scenes by the MXML compiler into ActionScript 3 before being compiled again.

But you probably didn’t buy this book to learn about interfaces or E4X, so we rushed through this chapter so that we could get to the cool stuff as soon as possible. Now that we’ve made it through this chapter, and you learned a bit of ActionScript along the way, we’ll slow down a bit and do what we came here to do: learn Flex 4, specifically, the shiny Flex 4 that impressed you enough to buy the book in the first place.

Specifically, in chapters 3 and 4 we’ll focus on the new Spark primitives and components that you use daily in Flex 4: text controls, buttons, combo boxes, lists, and so forth. In chapter 5 we’ll explain the Halo components you still need to know about. In chapter 6 we’ll take a deep dive into formatting and validation, which hasn’t changed much from Flex 3 but that’s still essential knowledge for any Flex developer. Finally, in chapter 7 we’ll build the Twitter + Yahoo! Maps example that the entire interweb is buzzing about. In all these chapters, however, your knowledge of ActionScript 3 will be both used and deepened.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.134.17