how to work with event in Flex? - actionscript-3

import flash.events.Event;
public class RequestEvent extends Event
{
public static const REQUEST:String = "request";
private var Results:Boolean;
public function get Results():Boolean
{
return _Results;
}
public function RequestEvent(Results:Boolean=false)
{
super(REQUEST);
Results = Results;
}
override public function clone():Event
{
return new RequestEvent(Results);
}
}
}
hi can some body explain why we are doing overridding of function clone and calling super(request), new in flex ........so don't mind.

One needs to implement the clone method just so that Flex could re-clone the event in the case when an event handler wishes to dispatch the same event again. Flex does provide a default implementation but one may override the method to clone the event differently, if need be.
As for calling the super method, you must call the super becasue you are extending the Event class. The type (in your case, REQUEST) must be a unique string that would uniquely identify the event to Flex platform.
Hope it helps
Regards.

The question about the overriding of the clone method in custom events is very popular and it seems to be one of the Flex strange things. You can read about it here.
So you have to override this method and only in this method you can define values of custom properties. The method is not usual, so if you try to debug it you will never get the debugger in its body.
If you try to define the value of your custom property in the constructor, the value will be ignorred.
It can be unpractical to use a constant string as the event's type value. In this case all instances of your RequestEvent are of the same type and you could not tell them appart using in different situations. As you can see in the example below, this string is used in action listener to map the listener function.
In this example I have three buttons with different events - normal Event, my version of RequestEvent and your version of it. Have a look at it, I hope it can help to understand the case.
//Application
<fx:Script>
<![CDATA[
import fld02.com.customevent.RequestEvent;
import fld02.com.customevent.RequestEvent2;
import mx.controls.Alert;
private function onCustomGroupBtn2Clicked(evt:RequestEvent):void
{
Alert.show('Btn2Clicked: results = ' + evt.results.toString(), 'This is RequestEvent');
}
private function onCustomGroupBtn3Clicked(evt:RequestEvent2):void
{
Alert.show('Btn3Clicked: Results = ' + evt.Results.toString(), 'This is your RequestEvent');
}
]]>
</fx:Script>
<customevent:CustomGroup
BUTTON1_CLICKED="{Alert.show('Btn1Clicked', 'This is Event')}"
BUTTON2_CLICKED="onCustomGroupBtn2Clicked(event)"
request="onCustomGroupBtn3Clicked(event)"/>
</s:Application>
//CustomGroup
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="346" height="144">
<fx:Metadata>
[Event(name="BUTTON1_CLICKED", type="flash.events.Event")]
[Event(name="BUTTON2_CLICKED", type="fld02.com.customevent.RequestEvent")]
[Event(name="request", type="fld02.com.customevent.RequestEvent2")]
</fx:Metadata>
<fx:Script>
<![CDATA[
private function onBtn1Click():void
{
this.dispatchEvent(new Event("BUTTON1_CLICKED"));
}
private function onBtn2Click():void
{
var requestEvent:RequestEvent = new RequestEvent("BUTTON2_CLICKED");
requestEvent.results = true;
this.dispatchEvent(requestEvent);
}
]]>
</fx:Script>
<s:Button x="43" y="31" width="183" label="Generate Event" click="onBtn1Click()"/>
<s:Button x="43" y="62" width="183" label="Generate RequestEvent" click="onBtn2Click()"/>
<s:Button x="43" y="93" width="183" label="Generate Your RequestEvent" click="{this.dispatchEvent(new RequestEvent2(true))}"/>
</s:Group>
//My RequestEvent
package fld02.com.customevent
{
import flash.events.Event;
public class RequestEvent extends Event
{
private var _results:Boolean;
public function RequestEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
override public function clone():Event
{
var requestEvent:RequestEvent = new RequestEvent(this.type);
requestEvent.results = this.results;
return requestEvent;
}
public function get results():Boolean
{
return _results;
}
public function set results(value:Boolean):void
{
_results = value;
}
}
}
//Your RequestEvent
package fld02.com.customevent
{
import flash.events.Event;
public class RequestEvent2 extends Event
{
public static const REQUEST:String = "request";
public function RequestEvent2(Results:Boolean=false)
{
super(REQUEST);
Results = Results;
}
private var _Results:Boolean;
public function get Results():Boolean
{
return _Results;
}
override public function clone():Event
{
return new RequestEvent2(Results);
}
}
}

Related

Flex Background Worker disposing of failed MessageChannel freezes application

I have the following scenario: I am using a MessageChannel to communicate with a background worker in a flex application. Since the code is to eventually be transformed into a library, it should also be able to handle malformed input (e.g. sending classes via the channel for which no class alias is registered in the background worker). In this case I want to abort the worker. My code is the following:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.system.MessageChannel;
import flash.system.Worker;
public class BW extends Sprite
{
/** Incoming channel */
private var fromCoordinatorChannel:MessageChannel;
/** Outgoing channel */
private var toCoordinatorChannel:MessageChannel;
public function BW()
{
super();
initChannels();
}
/**
* Get channels from shared property and attach event listener
*/
private function initChannels():void {
// Get channnels from shared property
fromCoordinatorChannel = Worker.current.getSharedProperty("toWorkerChannel");
toCoordinatorChannel = Worker.current.getSharedProperty("fromWorkerChannel");
// Attach event listener for incoming messages
fromCoordinatorChannel.addEventListener(Event.CHANNEL_MESSAGE, onIncomingMessage);
}
/**
* Event handler for incoming messages on the channel.
* #param event Event that came in
*/
private function onIncomingMessage(event:Event):void {
handleIncoming();
}
/**
* Get oldest message from channel and handle it
*/
private function handleIncoming():void {
if(fromCoordinatorChannel.messageAvailable) {
try {
var wm:Object = fromCoordinatorChannel.receive(true);
} catch(e:Error) {
fromCoordinatorChannel.close();
trace("Invalid type of package sent - could not be deserialized.");
// Kill myself
fromCoordinatorChannel = null;
toCoordinatorChannel = null;
Worker.current.setSharedProperty("toWorkerChannel", null);
Worker.current.setSharedProperty("fromWorkerChannel", null);
Worker.current.terminate();
}
}
}
}
}
And in the primordial worker:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
var worker:Worker;
var to:MessageChannel;
var from:MessageChannel;
var graveyard:Array = new Array();
private function removeWorkerIfFailed():void {
if(worker && worker.state == WorkerState.TERMINATED) {
from.close();
worker = null;
// What the actual f***? If I allow this channel to be garbage collected, it breaks. If I prevent that, it doesn't (o.Ó)
graveyard.push(to);
to = null;
from = null;
}
}
protected function button1_clickHandler(event:MouseEvent):void
{
registerClassAlias("Example", Example);
// Create worker and channels
worker = WorkerDomain.current.createWorker(Workers.BW);
to = Worker.current.createMessageChannel(worker);
from = worker.createMessageChannel(Worker.current);
// Attach event listener to status of worker so its reference can be deleted when it fails
worker.addEventListener(Event.WORKER_STATE,function(event:Event):void {removeWorkerIfFailed();});
// Set shared properties so worker can access channels
worker.setSharedProperty("toWorkerChannel", to);
worker.setSharedProperty("fromWorkerChannel", from);
// Attach event listener for incoming messages
from.addEventListener(Event.CHANNEL_MESSAGE, function(event:Event):void { trace('incoming'); });
// Start the worker
worker.start();
var example1:Example = new Example("one");
to.send(example1);
}
]]>
</fx:Script>
<s:Button label="Do it" click="button1_clickHandler(event)">
</s:Button>
</s:WindowedApplication>
Add the Example class
package
{
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.IExternalizable;
public class Example implements IExternalizable
{
public var name:String;
public function Example(name:String)
{
this.name = name;
}
public function readExternal(input:IDataInput):void
{
name = input.readUTF();
}
public function writeExternal(output:IDataOutput):void
{
output.writeUTF(name);
}
}
}
The problem is the following: If I remove the line in the removeWorkerIfFailed() that pushes a reference to the array (thereby preventing the channel from being garbage collected), the main application freezes. The debugger does not show any active function calls. As long as that line is there, everything works fine.
To reiterate: I know that in order to fix it, I need to call the registerClassAlias(...) also in the background worker, but I am trying to handle precisely this case that someone throws something wrong at the background worker.
Thank you

How do i re use this class in all my mxml components

Please i am new to Flex and Actionscript 3, but i know its an OOP language, I'm coming from a Java Background. I have a class that helps me check if the user of my AIR app has an internet connection it works well when included directly in my mxml class. Wanted to know if its possible to insert it in an actionscript class and reuse it in any mxml component class i wish to.
EDIT
package components
{
import air.net.URLMonitor;
import flash.events.StatusEvent;
import flash.net.*;
public class NetworkChecker
{
private var monitor:URLMonitor;
private var myURL = new URLRequest("http://www.adobe.com");
public function NetworkChecker()
{
myURL.method = "HEAD";
monitor = new URLMonitor(myURL);
monitor.start();
monitor.addEventListener(StatusEvent.STATUS, on_Connection);
}
public function on_Connection(event:StatusEvent):void
{
if(event.target.available == true)
{
trace("Internet Connection is available");
}
else
{
trace("No internet Connection");
}
}
}
}
Please how do i call this code from an mxml component? it works well when i include it directly in the fx:Script tag. I need to know if event.target.available is true of false in my mxml component...
Change your function to:
public function on_Connection(event:StatusEvent):boolean
{
if(event.target.available == true)
{
trace("Internet Connection is available");
return true;
}
else
{
trace("No internet Connection");
return false;
}
}
or better still:
public function on_Connection(event:StatusEvent):boolean
{
return event.target.available;
}
NOTE: this assumes that event.target.available is defined...
Add public proprerty to NetworkChecker class
[Bindable]
public var available:Boolean = false;
then
public function on_Connection(event:StatusEvent):void
{
this.available = event.target.available;
}
mxml
<fx:Declarations>
<components:NetworkChecker id="checker"/>
</fx:Declarations>
<s:Button label="Button" enabled="{checker.available}"/>
and more:
You should add eventListener before monitor start in constructor function

using getDefinitionByName correctly

here is my code line :
new (getDefinitionByName(String( "mypackage.MyDynamicClass" )) as Class) ;
This generates an error : mypackage.MyDynamicClass is not defined.
I googled and found a solution : Use the name of the class in the import statement.
So,
import mypackage.MyDynamicClass
new (getDefinitionByName(String( "mypackage.MyDynamicClass" )) as Class) ;
It worked!!!
but, I am not satisfied with this solution, as it really violates the benefit of a dynamic class. If i know the name of the class ( in import ), then why i would be using it as a string ?
Any alternatives to make dynamic loading of classes work ?
Vishwas
Take look at this article: http://blogs.adobe.com/cantrell/archives/2010/09/loading-classes-dynamically-in-actionscript-3.html
You cannot avoid including the classes you need at the runtime. You can always use:
import mypackage.*
Be aware at the fact that including all the classes in the package might increase the code size.
It definitely not violating dynamic loading of Class because of our compiler detect unused class/import statement in our project then get rid of those class file for packed as swc or swf so the advantage of our final output file size can reduce.
Unless few times unable reduce file size.
Probably you know what are the class you are trying to load via getDefinitionByName() before make sure that class available in IncludeClass.as
For better way, you can import statement for your project
package
{
public class IncludeClasses
{
import com.abc.db.Database; Database;
import com.abc.RemoteLogTarget; RemoteLogTarget;
import com.abc.LocalLogTarget; LocalLogTarget;
import com.abc.exception.GlobalExceptionHandler; GlobalExceptionHandler;
import com.abc.utils.NetConnectionMonitor; NetConnectionMonitor;
}
}
Stil you want to use your way better you can try with compiler options.
I suggest that you use a abstract factory
http://en.wikipedia.org/wiki/Abstract_factory_pattern
Its a very flexible way to create objects without knowing wich class you are going to instantiate.
Is in this abstract factory class in wich you will need to import all the clases you might create objects from, this will not require you to import all clases in your main class but you will still need to import the abstract factory and the interface to communicate with your new objects.
Here is a quick example:
/*
The interface you will use to communicate with your objects
*/
InterfaceForAllMyClasses.as
public interface InterfaceForAllMyClasses
{
public function callMe();
public function callMe2();
}
/*
Your Classes wich implement the interface
*/
Class1.as
import mypackage.InterfaceForAllMyClasses;
public class Class1 implements InterfaceForAllMyClasses
{
public function callMe() { trace("called Class1"); }
public function callMe2() { trace("called Class1 too"); }
}
Class2.as
import mypackage.InterfaceForAllMyClasses;
public class Class1 implements InterfaceForAllMyClasses
{
public function callMe() { trace("called Class2"); }
public function callMe2() { trace("called Class2 too"); }
}
/*
The Abstract Factory
*/
AbstractFactory.as
import mypackage.InterfaceForAllMyClasses;
public class AbstractFactory
{
public function giveMeObject(classNumber:Number):InterfaceForAllMyClasses
{
switch(classNumber)
{
case 0: return(new Class1()); break;
case 1: return(new Class2()); break;
// for any new class that you add you must add a case entry here
}
}
}
/*
Your Program
*/
import mypackage.InterfaceForAllMyClasses;
import mypackage.AbstractFactory;
MyProgram.as
public class MyProgram
{
var abstractFactory:AbstractFactory = new AbstractFactory();
public function main()
{
var x:InterfaceForAllMyClasses=AbstractFactory.giveMeObject(0);
var y:InterfaceForAllMyClasses=AbstractFactory.giveMeObject(1);
x.callMe();
x.callMe2();
y.callMe();
y.callMe2();
}
}
If you cant import the classes from your main application because they are declared in external modules (swfs), then you can make each module as an Abstract Factory, here is an example:
Interfaces/IModuleInterface.as
package Interfaces
{
public interface IModuleInterface
{
function giveMeObject(classNumber:Number):IObjectInterface;
}
}
Interfaces/IObjectInterface.as
package Interfaces
{
public interface IObjectInterface
{
function callMe():void;
function callMeToo():void;
}
}
Modules/ModuleOne.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Module xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300" implements="Interfaces.IModuleInterface">
<fx:Script>
<![CDATA[
import Interfaces.IObjectInterface;
public function giveMeObject(classNumber:Number):IObjectInterface
{
switch(classNumber)
{
case 1:
trace("ModuleOne: Instantiating 1");
return(new ModuleOneClassOne());
break;
case 2:
trace("ModuleOne: Instantiating 2");
return(new ModuleOneClassTwo());
break;
}
return(null);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Label x="10" y="10" text="Module One Loaded"/>
</s:Module>
Modules/ModuleOneClassOne.as
package Modules
{
import Interfaces.IObjectInterface;
public class ModuleOneClassOne implements IObjectInterface
{
public function ModuleOneClassOne()
{
trace("ModuleOneClassOne: Instantiated");
}
public function callMe():void
{
trace("ModuleOneClassOne: called callMe()");
}
public function callMeToo():void
{
trace("ModuleOneClassOne: called callMeToo()");
}
}
}
Modules/ModuleOneClassTwo.as
package Modules
{
import Interfaces.IObjectInterface;
public class ModuleOneClassTwo implements IObjectInterface
{
public function ModuleOneClassTwo()
{
trace("ModuleOneClassTwo: Instantiated");
}
public function callMe():void
{
trace("ModuleOneClassTwo: called callMe()");
}
public function callMeToo():void
{
trace("ModuleOneClassTwo: called callMeToo()");
}
}
}
AbstractFactoryInModules.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="345" height="200">
<fx:Script>
<![CDATA[
import Interfaces.IModuleInterface;
import Interfaces.IObjectInterface;
import mx.events.ModuleEvent;
protected var module:IModuleInterface;
protected var object:IObjectInterface;
protected function ButtonLoadSwf_clickHandler(event:MouseEvent):void
{
loader.unloadModule();
loader.url=moduleUrl.text;
}
protected function loader_readyHandler(event:ModuleEvent):void
{
this.module = (loader.child) as IModuleInterface;
}
protected function ButtonCreateObject_clickHandler(event:MouseEvent):void
{
this.object = this.module.giveMeObject(Number(TClassNumber.text));
}
protected function BCallMe_clickHandler(event:MouseEvent):void
{
this.object.callMe();
}
protected function BCallMeToo_clickHandler(event:MouseEvent):void
{
this.object.callMeToo();
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Button id="ButtonLoadSwf" x="236" y="10" width="99" label="Load SWF"
click="ButtonLoadSwf_clickHandler(event)"/>
<s:Button id="ButtonCreateObject" x="150" y="108" label="Create Object"
click="ButtonCreateObject_clickHandler(event)"/>
<s:TextInput id="TClassNumber" x="96" y="107" width="46" text="1"/>
<s:ModuleLoader x="10" y="39" width="325" height="60" id="loader" ready="loader_readyHandler(event)">
</s:ModuleLoader>
<s:TextInput id="moduleUrl" x="10" y="10" width="218" text="Modules/ModuleOne.swf"/>
<s:Button id="BCallMe" x="96" y="137" width="150" label="callMe"
click="BCallMe_clickHandler(event)"/>
<s:Button id="BCallMeToo" x="96" y="166" width="150" label="callMeToo"
click="BCallMeToo_clickHandler(event)"/>
</s:WindowedApplication>

Trying to use BindingUtils in Flash AS3.0

I am not able to make this code work in AS3.0 ( Flash ) with Flex SDK 4.0 included.
import mx.binding.utils.*;
[Bindable]
var myValue:int = 0;
var cw:ChangeWatcher = BindingUtils.bindSetter(myValueChanged, this, "myValue");
addEventListener( Event.ENTER_FRAME , ef);
function ef(e:Event):void
{
trace("hello",getTimer());
myValue = getTimer();
}
function myValueChanged(o:Object):void
{
trace("myValue: " + myValue.toString());
}
The output i get is :
myValue: 0
hello 157
hello 168
hello 171
hello 177
....
....
and so on.
But I expect the correct output should be :
myValue: 0
hello 157
myValue: 157
hello 168
myValue: 168
hello 171
myValue: 171
hello 177
myValue: 177
....
....
Thanks.
Data binding only works with Flex.
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" enterFrame="ef(event)">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.binding.utils.*;
[Bindable]
public var myValue:int = 0;
private var cw:ChangeWatcher = BindingUtils.bindSetter(myValueChanged, this, "myValue");
private function ef(e:Event):void
{
trace("hello", getTimer());
myValue = getTimer();
}
private function myValueChanged(o:Object):void
{
trace("myValue: " + myValue.toString());
}
]]>
</fx:Script>
</s:WindowedApplication>
I'm not exactly sure how the Flash Pro compiler treats this stuff (I always use the free mxmlc compiler from the Flex SDK).
Does this work for you?
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.utils.getTimer;
import mx.binding.utils.BindingUtils;
public class BindingExample extends Sprite {
private var model:Model;
public function BindingExample()
{
model = new Model();
BindingUtils.bindProperty(this, 'spy', model, ['value']);
addEventListener( Event.ENTER_FRAME , onEnterFrame);
}
public function onEnterFrame(e:Event):void
{
model.value = getTimer();
}
public function set spy(value:int):void
{
trace('Bound property set to: ' + value);
}
}
}
class Model
{
[Bindable]
public var value:int;
}
If not, try this for the Model definition:
import flash.events.Event;
import flash.events.EventDispatcher;
class Model extends EventDispatcher
{
private var _value:int;
[Bindable("valueChange")]
public function get value():int
{
return _value;
}
public function set value(value:int):void
{
if (_value != value)
{
trace('Model property set to: ' + value);
_value = value;
dispatchEvent(new Event("valueChange"));
}
}
}
If that doesn't work, try this for the Model:
import flash.events.EventDispatcher;
import mx.events.PropertyChangeEvent;
import mx.events.PropertyChangeEventKind;
class Model extends EventDispatcher
{
private var _value:int;
[Bindable("propertyChange")]
public function get value():int
{
return _value;
}
public function set value(value:int):void
{
if (_value != value)
{
trace('Model property set to: ' + value);
var oldValue:int = _value;
_value = value;
dispatchEvent(new PropertyChangeEvent(
PropertyChangeEvent.PROPERTY_CHANGE, false, false,
PropertyChangeEventKind.UPDATE, "value", oldValue, value, this));
}
}
}
Or, perhaps with an ObjectProxy:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.utils.getTimer;
import mx.binding.utils.BindingUtils;
import mx.utils.ObjectProxy;
public class BindingExample extends Sprite {
private var model:ObjectProxy;
public function BindingExample()
{
model = new ObjectProxy({value: 0});
BindingUtils.bindProperty(this, 'spy', model, ['value']);
addEventListener( Event.ENTER_FRAME , onEnterFrame);
}
public function onEnterFrame(e:Event):void
{
model.value = getTimer();
}
public function set spy(value:int):void
{
trace('Bound property set to: ' + value);
}
}
}
All of the above work fine when compiling with mxmlc. I'd avoid the ObjectProxy as it's the least typesafe.
You wrote:
I am not able to make this code work in AS3.0 ( Flash ) with Flex SDK 4.0 included.
I take it this means you are already using the mxmlc compiler, which is necessary for the Bindable metatag to work.
As I understand it, adding the Bindable meta tag to a variable is a way to listen for dispatches of a PropertyChangeEvent:
The Flex 4.6 API docs state:
[When using Bindable on a variable] The Flex compiler automatically generates an event named propertyChange, of type PropertyChangeEvent, for the property.
Basically a simpler way to do myValue.addEventListener(...)
So the variable we want to be Bindable must be of a type that extends EventDispatcher or implements IEventDispatcher. This is not the case with the primitive int which is the type of the variable you are trying to make bindable. Bindable on an int will not work.
To make it work you could wrap the int variable in a custom class BindableInteger that implements IEventDispatcher. Another options is to use ObjectProxy, which allows you to add EventListeners and make an object bindable even though it doesn't extend EventDispatcher or implements IEventDispatcher.
Also, note that you need to make your variable public, protected or private for Bindable to work.
Flex 4.6 docs on Using the Bindable meta tag:
You can use the [Bindable] metadata tag (...) [b]efore a public, protected, or private property defined as a variable to make that specific property support binding.
This will not work:
[Bindable] var myValue:int = 0;
but this will:
[Bindable] public var myValue:int = o;
Binding works for class properties, and doesn't work with local variables so you need to create the class:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.utils.getTimer;
import mx.binding.utils.BindingUtils;
import mx.binding.utils.ChangeWatcher;
public class astest extends Sprite
{
[Bindable]
public var myValue:int = 0;
public function astest()
{
var cw:ChangeWatcher = BindingUtils.bindSetter(myValueChanged, this, "myValue");
addEventListener( Event.ENTER_FRAME , ef);
}
protected function ef(e:Event):void
{
trace("hello",getTimer());
myValue = getTimer();
}
protected function myValueChanged(o:Object):void
{
trace("myValue: " + myValue.toString());
}
}
}

Send data from popup to main application.

I'm not getting the answer I'm looking for.
I want to send the request data i get to the main application.
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" remove="titlewindow1_removeHandler(event)"
width="400" height="220" layout="absolute" title="USER LOGIN">
<mx:Metadata>
[Event(name="commEvent", type="flash.events.Event")]
</mx:Metadata>
<mx:Script>
<![CDATA[
import data.Data;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
[Bindable]
public var userID:String;
private function loginUser():void{
trace("btn");
var req:URLRequest = new URLRequest('http://localhost/CCN/userProcess.php');
var loader:URLLoader = new URLLoader();
req.method="POST";
var variables:URLVariables = new URLVariables();
variables.email= username.text;
variables.password= password.text;
variables.action= "login_user";
req.data=variables;
loader.addEventListener(Event.COMPLETE,onDataLoaded);
loader.load(req);
}
protected function loginButton_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
loginUser();
}
private function onDataLoaded(e:Event):void{
var xml:XML= new XML(e.target.data);
if(xml.status=="success"){
//SEND DATA TO MAIN APPLICATION ????
PopUpManager.removePopUp(this);
}else{
fail.visible=true;
username.text="";
password.text="";
username.setFocus();
}
}
protected function loginButton_keyDownHandler(ee:KeyboardEvent):void
{
// TODO Auto-generated method stub
if(ee.keyCode==13){
loginUser();
}
}
protected function titlewindow1_removeHandler(event:FlexEvent):void
{
// TODO Auto-generated method stub
}
]]>
</mx:Script>
<mx:TextInput id="username" x="141" y="31" width="199" text=""/>
<mx:TextInput keyDown="loginButton_keyDownHandler(event)" text="000" id="" x="141" y="84" width="199" displayAsPassword="true"/>
<mx:Button id="loginButton" x="275" y="133" label="LOGIN" click="loginButton_clickHandler(event)"/>
<mx:Label x="22" y="33" text="Email"/>
<mx:Label x="22" y="86" text="Password"/>
<mx:Label x="22" visible="false" y="135" id="fail" color="#FF0000" text="LOGIN FAILED"/>
</mx:TitleWindow>
here is the main application code
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
minWidth="955" minHeight="600" backgroundColor="#FFFFFF"
creationComplete="application1_creationCompleteHandler(event)" layout="absolute">
<mx:Script>
<![CDATA[
import mx.containers.TitleWindow;
import mx.core.IFlexDisplayObject;
import mx.events.CloseEvent;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
//private var loginWindow:TitleWindow;
public var user:String;
private var login:Login
private function application1_creationCompleteHandler(event:FlexEvent):void
{
// TODO Auto-generated method stub
login = Login(
PopUpManager.createPopUp(this, Login, true));
PopUpManager.centerPopUp(login);
//login['loginButton'].addEventListener(MouseEvent.CLICK,onClose);
login.addEventListener(CloseEvent.CLOSE,oncc)
}
private function onClose(e:Event):void{
trace("Trace : "+login.userID);
}
private function
]]>
</mx:Script>
</mx:Application>
I would recommend solving this by adding a custom event, as your tag implies you may understand.
If not, here are the steps you would follow.
1) Create a new Event type (extend the Event class in actionscript - be sure to override clone())
2) Add an event listener for your new Event type in the parent application on the popup
3) cause the popup to dispatch your new Event type before it closes
4) Handle whatever it is you're looking for (userID?) in the event handler.
I would recommend attaching the userID to the actual event, so that the parent is not directly addressing login.userID. From a loose coupling standpoint, it's more correct. That said, if you don't wish to, you can simplify the solution by NOT attaching the userID. Loose coupling is a great goal, but if you only plan to use this relationship once, it's not incredibly necessary.
If you choose to go the tighter coupling route, then you only have to dispatch an event with a custom "type" instead of an extended Event.
If you need a lower level example (less description, more code) let me know, and I can help with that as well.
The example provided below is the slightly more complex version, where you extend an event to contain the data.
Event class::
package mycomponents
{
import flash.events.Event;
public class CustomEvent extends Event
{
public static const EVENT_TYPE_NAME:String = "myEventType"
public var mUserID:String = "";
public var mSuccess:Boolean = false;
public function CustomEvent(aType:String, aUserID:String, aSuccess:Boolean)
{
super(aType)
mUserID = aUserID;
mSuccess = aSuccess;
}
override public function clone():Event
{
var lEvent:CustomEvent = new CustomEvent(mUserID, mSuccess);
return lEvent;
}
}
}
In Popup::
private var loginSuccessful:Boolean = false;
private function onDataLoaded(e:Event):void{
var xml:XML= new XML(e.target.data);
if(xml.status=="success"){
userID = username.text;
loginSuccessful = true;
//SEND DATA TO MAIN APPLICATION
dispatchEvent(new CustomEvent(CustomEvent.EVENT_TYPE_NAME, userID, loginSuccessful );
PopUpManager.removePopUp(this);
}else{
fail.visible=true;
username.text="";
password.text="";
username.setFocus();
}
}
protected function titlewindow1_removeHandler(event:FlexEvent):void
{
if (!loginSuccessful)
dispatchEvent(new CustomEvent(CustomEvent.EVENT_TYPE_NAME," userID, loginSuccessful ));
}
And in the Main Application::
import mycomponents.CustomEvent;
private function application1_creationCompleteHandler(event:FlexEvent):void
{
//...your code
login.addEventListener(CustomEvent.EVENT_TYPE_NAME, handleLoginEvent);
}
private function handleLoginEvent(aEvent:CustomEvent)
{
//My example code dispatches an event with mSuccess = false if the login prompt closes
//without a successful login
//
//now do whatever you want with the information from the popup
//aEvent.mUserID gets you ID
//aEvent.mSuccess gets you success
}
Tossed that together in the middle of a break at work, so no promises will compile as-is.