How to call some mxml function from class? - actionscript-3

I have 2 files: Main.mxml with application and one MyObject.as.
I create the instance of MyObject in mxml and can call its every public function from mxml. But what if for some reason I need to call some function declared in mxml from MyObject class? How to do that? I thought that I could pass the reference to main.mxml class into this object but I couldn't figure out what exact class is it (it inherits Application, right, but what exact class is it?)
Thanks

It is of type Main (it takes on the name of the mxml file). You can add a static variable and getter method to it:
private static var _instance : Main;
public static function get instance () : Main {
return _instance;
}
Then let instance refer to this after the application is complete:
private function applicationCompleteHandler():void
{
_instance = this;
}
Don't forget to set applicationComplete="applicationCompleteHandler" in your <mx:Application> tag.
After that you can call Main.instance from anywhere in your program to access the methods and variables.

If you are instantiating the MyObject class in your Main.mxml, you could also accomplish access to a method in Main by passing the method as a Function into the object.
Suppose you have in Main.mxml the function:
private function doSomething():*{
...
}
With an appropriate setter in MyObject.as:
private var _mainFunction:Function;
public function set mainFunction(f:Function):void
{
_mainFunction = f;
}
Then you can pass the method when you instantiate the MyObject class in the mxml:
<*:MyObject mainFunction='doSomething'/>
And now you just call _mainFunction in the MyObject.as code whenever you need it.
Of course, Weltraumpirat's suggestion would be more efficient if you needed to access more than one method and/or variable on your Application.

Related

Bindable(event="...") public static function

I am trying to bind to a static function, I designate a binding event name and then fire the event from another static function.
[Bindable(event="dataUpdated")]
public static function string(path:String) :String
{
...
}
private static function updateData() :void
{
//doSomthing;
staticEventDispatcher.dispatchEvent(new Event('dataUpdated'));
}
private static var staticEventDispatcher:EventDispatcher = new EventDispatcher();
My view is not updating when the event is fired, is there a better way to do this?
I have also tried dispatching the event from an instance of the class, I added this staticEventDispatcher as a last resort, but it didn't work.
The point in this if for language translations within the app, MyClass.string('stringPath') will return the translated component text. I need the app text to be updated when the user changes their language.
Binding doesn't work with static properties and methods (see this question for details Binding to static property).
In your case it's better to use the singleton pattern for resource manager and remove static from string and updateData:
MyClass.instance.string('stringPath')
and MyClass:
public static const instance:MyClass = new MyClass();

Static Stop/Play Functions

Let's say I would want to use the frameScript method to add some stop and play methods to some frames.
Normally I would declare the stop function:
private function $FUN_FrameStop():void {
stop();
return;
}
and then use it like this:
addFrameScript(47, $FUN_FrameStop, 122, $FUN_FrameStop);
My question is, how can I create the same $FUN_FrameStop as a static function?
Static functions do not allow the use of this since static members are bound to a class and are not inherited by that class' instances.
So, is there a way to create a function similar to $FUN_FrameStop, but static?
I never added any frame script dynamically but.. did you try using the instance as the parameter?
private static function $FrameStop($inst:MovieClip):void {
$inst.stop();
}
The answer is that there's no way unless I have a static reference to the class instance, but that's not what I want.
public static var staticClassRef:MovieClip;
function $FUN_FrameStop():void {
staticClassRef.stop();
return;
}
You may declare a function outside of class but in package
package
{
public function Func(): void
{
trace( "Func" );
}
}
then you may call it everywhare with Func() after including the package ( if needed )

Calling private function from external ActionScript3 File

How do I call a private function from an external ActionScript3 document? I'm working in Flash Builder 4, and I need to call a private function from an external AS3 document. I think I've imported it correctly....
import myapp.utils.WebcamFaceDetector;
import myapp.utils.FaceDetector;
But I want to call a function from "FaceDetector". Here's the part of the code in FaceDetector...
public class FaceDetector
{
private var detector :ObjectDetector;
private var options :ObjectDetectorOptions;
private var faceImage :Loader;
private var bmpTarget :Bitmap;
private var view :Sprite;
private var faceRectContainer :Sprite;
private var tf :TextField;
private function FaceDetector() {
initDetector();
}
//...
}
I want to call "private function FaceDetector()" to initiate at a certain point in another AS3 file. How do I properly declare it and get it to run?
The only way to access a private function it is to declare it as public or introduce an extra function and declare that as public.
The private attribute is meant to restrict access to that Class alone.
What you can do is create a protected function that subclasses your FaceDetector class and that gives you access but maybe not in the way that you want to use it.
On closer inspection you are using a private constructor (unless this is not your package) which prevents instantiation from other classes so I am not sure what you are really trying to accomplish.
If is was a normal private function (not a constructor) you could also register it to listen for events and and dispatch the event from where-ever you need it from.
The only proper way I know of to use private constructors other than utility classes are Singletons and that cannot even be done in ActionScript 3 (private constructors)
From your example code, the FaceDetector function is the contructor of the FaceDetector class. This means it is called when you construct a new instance of FaceDetector e.g.
var faceDetectorInstance:FaceDetector = new FaceDetector();
your constructor should be public not private. AS3 does not support private constructors.
you should make your initDetector method public, so you can call that directly e.g.
public function initDetector():void
{
//Do Stuff Here...
}
First, you cannot call a private class. The private keyword purpose is to stop external classes, including subclasses from calling the function.
Second, FaceDetector has the same name as the class. This means it is the constructor and is automatically called when you create a new instance of the class.
PS. Constructors in ActionScript 3.0 must be public

ActionScript Calling Private Functions By Changing Public Variables?

i've never tried to do this before, so my head a swimming a bit. i'd like to have a public boolean called enabled in myClass custom class. if it's called to be changed, how do i trigger a function from the change?
should i add an Event.CHANGE event listener to my variable? can i do that? or is there a more standard way?
We usually use properties for that.
Properties are just like public variables for the outside -- you can set instance.enabled = true; and so forth.. But you define properties as getters and/or setters functions for the class.
They are the perfect place for custom logic to be executed on value changes.
For example:
public class CustomClass {
private var _enabled:Boolean = false;
public function set enabled(value:Boolean):void {
trace('CustomClass.enabled is now', value);
this._enabled = value;
}
public function get enabled():Boolean {
trace('CustomClass.enabled was retrieved');
return this._enabled;
}
}
Note that they can't have the same name as your private variable and you don't need both of them defined. Actually, you don't even need a variable for a setter/getter. You could use them just like any function -- they just supply you with a different syntax.
For example:
var object:CustomClass = new CustomClass();
object.enabled = false;
if (object.enabled) {
...
}
They are great to expose a simple API, keeping you from rewriting outside code if the class' internals have to change.
AS3 Reference on getters and setters.

AS3 Vectors: using getters and setters?

Is there a way to use getters and setters for Vectors?
Say, in my Main class, I would like to write
myVector.push(item);
and in another class, I have written:
public function get myVector():Vector.<int> {
return _opponentCardList;
}
public function set myVector(myVector:Vector.<int>):void {
_myVector = myVector;
}
This doesn't really work as you have to set _myVector to a Vector. But what if you just want to push(), pop() or splice?
Your getter and setter use different variables - is that intentional?
If the getter/setter myVector is in a different class, you need an instance of that class in your Main class before you can access it from there.
//in the Main class.
var obj:OtherClass = new OtherClass();
//the constructor of OtherClass should initialize _myVector
//otherwise you will get a null pointer error (1009) in the following line
obj.myVector.push(item);