David is right -- while you can access the public members of your Application.mxml object statically and from anywhere in your application, design-wise that's a bit of a no-no. It's better to strive for loose coupling between your objects, and the way that's done in the Flex idiom is generally to extend EventDispatcher and to dispatch events. So for example, your WebService wrapper might look something like this:
public class MyWrapperClass extends EventDispatcher
{
[Event(name="webserviceComplete", type="flash.events.Event")]
public function MyWrapperClass(target:IEventDispatcher=null)
{
super(target);
}
private function handleWebServiceLoadComplete(event:ResultEvent):void
{
dispatchEvent(new Event("webserviceComplete"));
}
public function doWork():void
{
// Load the service, etc., and ultimately call handleWebServiceLoadComplete()...
}
}
... and your Main.mxml file like this:
<mx:Script>
<![CDATA[
private function app_creationComplete(event:Event):void
{
var myWrapper:MyWrapperClass = new MyWrapperClass();
myWrapper.addEventListener("webserviceComplete", mywrapper_webServiceComplete, false, 0, true);
myWrapper.doWork();
}
private function mywrapper_webServiceComplete(event:Event):void
{
// Do the work you would've otherwise done in the public method
}
]]>
</mx:Script>
In this case, the end result is the same -- completing the web-service load triggers the function in Main.mxml. But notice how mywrapper_webServiceComplete()
is declared privately -- it's not called directly by MyWrapperClass
. Main.mxml simply subscribes (with addEventListener()
) to be notified when MyWrapperClass is finished doing its work, and then does its own work; MyWrapperClass knows nothing about the details of Main.mxml's implementation, nor does Main.mxml know anything about MyWrapperClass other than that it dispatches a webserviceComplete
event, and exposes a public doWork()
method. Loose coupling and information hiding in action.
Good luck!
You don't have to make the method static; doing so would likely be useless, as you'd want the method call to do something with the component's current state, I'm guessing -- use some of its data, change its appearance, etc. What you really need is an object reference.
Since Application.application resides at the top (or actually very close to the top) of the fabled Display List, you should be able to access each component by starting at that point and then traversing the Display List -- until ultimately, upon arriving at your nested component, calling its publicly defined method.
However, I must say (with the utmost respect!) that you're venturing into dangerous OO waters, here. :) The right way to do this would really be to figure out some way to pass a reference to your custom component to the ActionScript class that requires access to it -- for example, in your MXML:
<mx:Script>
<![CDATA[
private function this_creationComplete(event:Event):void
{
var yourObject:YourClass = new YourClass(yourCustomComponent);
}
]]>
</mx:Script>
<components:YourCustomComponent id="yourCustomComponent" />
... and then in your ActionScript class:
public class YourClass
{
private var componentReference:YourCustomComponent;
public function YourClass(component:YourCustomComponent)
{
this.componentReference = componentReference;
}
private function yourMethod():void
{
this.componentReference.someMethodDefinedInYourComponent();
}
}
An approach like that would probably serve you better. Does it make sense? I'll keep an eye our for comments; post back and I'll do my best to help you through it.
Best Answer
By setting the id property of the MXML component you effectively make it a public property accessible via dot-notation. "Accessing it via MXML" is sort of a trick question. You can use binding notation within an xml tag and bind the property to another property, or you can access it in your Script block in the normal AS3 fashion.