views:

166

answers:

2

I'm trying to build a Flex AIR app using Flex Builder 3, which I'm just getting started with.

In Flash CS4, there's a text field in the authoring environment where you can specify a class that will become the "base" class - your class inherits from Sprite and then "becomes" the Stage at runtime. Is there a a way to do the same thing with Flex/AIR? Failing that, can anyone explain how to create and use an external class?

Originally I had this in TestApp.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Script source="TestApp.as"/>
</mx:WindowedApplication>

And this in TestApp.as:

package {
    public class TestApp {
        public function TestApp() {
            trace('Hello World');
        }
    }
}

That gives the error "packages cannot be nested", so I tried taking out the package statement:

public class TestApp {
    public function TestApp() {
        trace('Hello World');
    }
}

That gives an error "classes cannot be nested", so I finally gave up and tried to take out the class altogether, figuring I'd try to start with a bunch of functions instead:

function init() {
    trace('Hello World');
}

But that gives the error "A file found in a source-path must have an externally visible definition. If a definition in the file is meant to be externally visible, please put the definition in a package".

I can't win! When I put my class in a package, it says I can't do that because it would be nested. When I don't, it says it needs to be in a package so it can be seen.

Does anyone know how to fix this? If I can't do the custom-class-as-base-class thing, is there a way I could just have it like:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Script source="TestApp.as"/>
    <mx:Script>
        var app = new TestApp();
    </mx:Script>
</mx:WindowedApplication>

At the moment I can't import the class definition at all, so even that won't work.

Thanks in advance!

A: 

An MXML document is actually translated into an actionscript class. The filename indicates the class name and the root tag indicates the base class. So TestApp.mxml represents the "base" class, which is most commonly refered to as the document class.

Now if you want to use your own classes/mxml-components within MXML, you will need to import the namespace they are in (much like xmlns:mx="http://www.adobe.com/2006/mxml" imports the flex components), using xmlns:c="mycomponents.*". Thus if you had a custom class mycomponenty.Foo, you could use it as follows:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:c="mycomponents.*" >
    <c:Foo />
</mx:WindowedApplication>

also i suggest you take the habit of embeding inline scripts as cdata.

greetz

back2dos

back2dos
A: 

The mxml file named TestApp.mxml at the root of the class path creates a TestApp class in the default package.

When you include script using <mx:Script source="TestApp.as"/>, compiler just copies the contents of TestApp.as file to the mxml file as a CDATA block. Hence the packages/classes cannot be nested error. The third error is because the script file holds the same name as the class name (compiler knows that there is a TestApp class out there - but the file TestApp.as doesn't have a class declaration in it). If you rename TestApp.as to something else like TestApp_script.as and change the file path in the <mx:Script/> tag, you would be good to go.

And as already suggested, always write ActionScript in inline CDATA blocks instead of external script files - that's more maintainable. After all they both (mxml and the script) are part of the same class and they belong in the same file.

Amarghosh