18
Jul
2006

Flex tags and AS classes (continued)

In the previous post, I talked about how MXML tags map to ActionScript classes. I was planning on following that up with a short post about the exceptions to the earlier rules. However, a number of thoughtful comments helped me understand that there are more things that need explaining than just the original rules and the exceptions.

~

Instance variables and scoping

At the 50,000 foot level, all you need to know about MXML tags with ids is that they become variables. At the 10,000 foot level, you start caring what kind of variables these turn into.

Take, for example, the following block of code.

MyApp.mxml
--
<Application>
    <HBox>
        <Image id="theImage" src="foo.gif" />
        <Button id="theButton" label="hide image" click="theImage.visible = false" />
    </HBox>
</Application>

What kind of variable is theImage? Well, it sort of feels like a global variable. After all, you access it without any qualifiers. But if you think about it a bit more, you will realize that true global variables would be visible anywhere in your program, no matter what file you were in. These variables are only visible from within this file, right?

As it turns out, each MXML file corresponds to a new ActionScript class, and the objects with ids on them turn into instance variables of that class. The above code is roughly equivalent to the following:

class MyApp extends Application
{
    public var theImage : Image;
    public var theButton : Button;

    // In the real world, this initialization code is much
    // more complex and doesn't go in the constructor,
    // but you get the idea...
    public function MyApp()
    {
        var hbox = new HBox();

        theImage = new Image();
        theImage.src = foo.gif;
       
        hbox.addChild(theImage);

        theButton = new Button;
        theButton.label = "hide image";
        theButton.addEventListener("click", temp1);

        hbox.addChild(theButton);
        this.addChild(hbox);
    }

    private function temp1(event: MouseEvent) : void
    {
        theImage.visible = false;
    }
}

As you can see, theImage and theButton are member variables of the MyApp class. Note that it doesn’t matter where in the file these objects are defined. In this example, the image and button are inside of an hbox, but the variables are still defined on the outermost class, the application.

ActionScript inside MXML

Looking at the code example above, you will notice that event handlers are turned into functions. These functions are members of the outer class, and they have strongly typed signatures. In this case, an “event” parameter with the correct type is passed to the click handler. If you wanted to be perverse, you could even do things like define local variables within your inline event handler and it would all work just fine (although it is obviously not recommended).

What happens to ActionScript code inside of script blocks? Let’s take a look at the code below:

<Application>
    <Script>
    <![CDATA[
        [Bindable]
        var foo : String;

        public function bar() : void
        {
        }
    ]]>
    </Script>
</Application>

The code inside the script block is just inserted into the class definition, so this turns into:

class MyApp extends Application
{
        [Bindable]
        var foo : String;

        public function bar() : void
        {
        }
}

Any code you can put into the body of a class definition is valid in a Script block. This allows you to do things like attach metadata to getters and setters. And now that you know how the functions defined in MXML relate to the class, you now know how to access these methods from other objects. For example, if an MXML component defines functions like this:

PasswordEntry.mxml
--
<VBox>
    <Script>
        public function get username() : String
        {
            return usernameField.text;
        }

        public function get password() : String;
        {
            return passwordField.text;
        }

        public function reset() : void
        {
            usernameField.text = passwordField.text = "";
        }
    </Script>
    <HBox>
        <Label  text="username" />
        <TextInput id="usernameField" />
    </HBox>
    <HBox>
        <Label  text="password" />
        <TextInput id="passwordField" />
    </HBox>
</VBox>

You can invoke them from another file like this:

<Application>
    <Script>
        public function foo() : void
        {
            Alert.show("username: " + pw.username + " password: " + pw.password);
            pw.reset();
        }
    </Script>
    <PasswordEntry id="pw" />
    <Button label="foo" click="foo()" />
</Application>

What’s next?

Ok, so I still need to write a post about the exceptions to the rules. And I think I should probably do one about different ways to separate your code from your design, including the technique of using inheritance between AS and MXML.

10 Responses to “Flex tags and AS classes (continued)”

  1. pablo

    Please keep writing I’m passing these on to everyone I know who is working or planning on working in Flex. Great stuff.

  2. Ben

    Thanks for addressing the aspects we mentioned in the comments. I agree with Pablo; great stuff and please keep it coming.

  3. ilya Devers

    Hi Sho,

    Good stuff indeed.

    In the “theImage” example above, people might think (if they didn’t read careful) that these member Variables are always on the application Class (as in the example), but when they would occur on another MXML file (a component), they would be member variables of that class.

    cheers

  4. ebaggg

    Sho-
    This is a great article, thanks. These features should greatly reduce the amount of burden on the ViewLocators…for example, updating a component on another screen. Before, I would retrieve the view helper and then call a getter, but now I can access the components directly.

    You agree?

  5. syoavc

    This is a really helpful post, thanks.
    One thing that I still didn’t figure out is how to create component instances in MXML for classes with constructors that accept parameters.

  6. kuwamoto.org » Blog Archive » Flex tags and AS class (the exceptions)

    […] Here is the long overdue continuation of this topic. If you haven’t read the first two, you will probably want to at least skim this and this. Go ahead. I’ll wait. […]

  7. nwebb

    Excellent posts – thanks Sho.

  8. Etiquetas Flex y clases AS (continuación) at mx:bicherele

    […] (Esta es la traducción del artículo “Flex tags and AS classes (continued)” de Kuwamoto.) […]

  9. Etiquetas Flex y clases AS (continuación) : Bicherele

    […] and AS classes (continued)” de Kuwamoto.)  tag this | permalink | trackback url Leave aComment […]

  10. Bicherele » Archives » Etiquetas Flex y clases AS (continuación)

    […] (Esta es la traducción del artículo “Flex tags and AS classes (continued)” de Kuwamoto.) […]

Leave a Reply