Need to click twice on Flex button to get RemoteObject result - apache-flex

I'm doing a project using Java + Flex. I created Java class and used Flex remote object to invoke the method. When I write all the code in an mxml, it runs well. But when I wrap the script in an as file, there's something curious. I need to click twice on Flex button to get the result which returned by the remote object. I think there's something wrong with my as file.
Below is my MXML:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="500" minHeight="600">
<fx:Declarations>
<mx:RemoteObject id="Control" destination="Control" showBusyCursor="true" />
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.wntime.ControlUtil;
import mx.rpc.events.ResultEvent;
private var resultOfCmd:String;
private var cmdStr:String;
private var ct:ControlUtil = new ControlUtil();
/* invoke as method */
private function test():void
{
cmdStr = cmdTxt.text;
resultOfCmd = ct.exec(cmdStr);
cmdConsole.text = resultOfCmd;
}
/* */
private function exec():void{
cmdStr = cmdTxt.text;
Control.execCmd(cmdStr);
Control.addEventListener(ResultEvent.RESULT,execCmd_clickHandler);
}
private function execCmd_clickHandler(event:ResultEvent):void
{
cmdConsole.text = event.result.toString();
}
private function clearCmdConsole():void
{
cmdConsole.text = "";
}
]]>
</fx:Script>
<s:Panel id="CmdPanel" x="70" y="50" width="501" height="350" title="Command Execute Panel">
<s:RichText x="20" y="33" fontSize="14" text="Cmd:"/>
<s:TextInput id="cmdTxt" x="60" y="30" width="239"/>
<s:Button id="execCmd" x="312" y="30" width="68" label="execute" click="exec()"/>
<s:Button x="400" y="30" label="CmdTest" click="test()"/>
<s:TextArea id="cmdConsole" x="20" y="85" width="450" editable="false"/>
<s:Button x="400" y="250" label="clear" click="clearCmdConsole()"/>
</s:Panel>
</s:Application>
Here is the as file which named ControlUtil:
package com.wntime{
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.RemoteObject;
public class ControlUtil
{
private var cmd:String = null;
private var result:String = null;
private var roControl:RemoteObject = new RemoteObject();
public function ControlUtil()
{
roControl.destination = "Control";
}
public function exec(_cmd:String):String{
this.cmd = _cmd;
roControl.execCmd(cmd);
roControl.addEventListener(FaultEvent.FAULT, execCmd);
roControl.addEventListener(ResultEvent.RESULT, execCmd);
return result;
}
public function execCmd(event:ResultEvent):void
{
setResult(event.result.toString());
}
public function setResult(_result:String):void
{
this.result = _result;
}
}
}
If I click the execute button. The result will show in the console(the textarea) directly.
But I need to click twice on CmdTest button to get the result to show in the console.
Give me a hand plz.Thanks in advance.

This is just a wild guess, but I think the method you invoke at the Java side returns faster than you add your listeners, hence no event handler is called. The second time all listeners are in place and your call succeeds. Try adding your listeners before you invoke remote method.

Your code has various errors/problem in my opinion, I would do something like that:
package com.wntime{
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.RemoteObject;
public class ControlUtil
{
private var cmd:String = null;
private var result:String = null;
private var roControl:RemoteObject = new RemoteObject();
// the callBack function is the function that is called when the
// remoteobject successfully or not complete the request...
// you can set as parameters anything you want...
private var callBack:Function = null;
public function ControlUtil()
{
roControl.destination = "Control";
}
public function exec(callBack:Function, _cmd:String):void{
this.cmd = _cmd;
this.callBack = callBack;
roControl.addEventListener(FaultEvent.FAULT, errorCmd);
roControl.addEventListener(ResultEvent.RESULT, execCmd);
roControl.execCmd(cmd);
}
private function execCmd(event:ResultEvent):void
{
callBack(true,event.result.toString());
}
private function errorCmd(event:FaultEvent):void
{
callBack(false, event.error); // call the callBack function passing the value you need
}
}
}
the callBack function is something like that:
private function name(b:Boolean, s:String = null){....}
* EDIT *
from your main code you invoke the exec command...
// function invoked when the button is clicked!
private function buttonClick():void
{
var tmp:ControlUtil = new ControlUtil();
//exec(callBack:Function, _cmd:String)
//you pass the function as a reference so when the async request is terminated the function is invoked and you can parse the result....
tmp.exec(getResult, "cmqString");
}
// callBack function for the method ControlUtil.exec
private function getResult(b:Boolean, result:String = ""):void
{
if (b)
{
// the call returned correctly and the result variable contains the value.
}
else
{
// the call failed and the result variable contains the error
}
}
Both the boolean and the result value are returned because I specified it in the ControlUtil when i used callBack(true/false, result/error)
You can create the function as you prefer...

Related

How to pass parameters to a view that was previously shown in Flex Mobile Project (I cannot use pushView)

I have a Flex Mobile Project that I am working on. I am trying to pass parameters from one view to another. The only problem is that I cannot use navigator.pushView to push the View and the parameter as the view I am pushing to was the previous view. So this wipes out using the addHandler() and the returnObjectsCreated() as I cannot use pushView. I am having to use popView because it is my previous view that I have to pass parameters too. Any help would be appreciated.
That class that has the parameters I need to pass is below. It is a view that shows a list. So I need to pass list.selectedItem to the popview or previous view...
<?xml version="1.0" encoding="utf-8"?>
<amec:BaseBrowseView xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:amec="com.amec.Components.*"
title="Select an item">
<fx:Script>
<![CDATA[
import com.amec.BaseSql;
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import spark.events.IndexChangeEvent;
[Bindable]private var resultArr:ArrayCollection = new ArrayCollection();
protected function myList_changeHandler(event:IndexChangeEvent):void
{
navigator.popView();
//Either send a ref to the last view or override createReturn
}
[Bindable(event="myDataChanged")]
private function get myData():ArrayCollection
{
}
]]>
</fx:Script>
<s:List id="list"
height="100%" width="100%"
dataProvider="{myData}"
labelField="DMV_VALUE_1"
change="myList_changeHandler(event);">
</s:List>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
Now below is the previous view that I want to popView to that I need to pass parameters to so I can populate the TextInput with.
<?xml version="1.0" encoding="utf-8"?>
<amec:BaseControl xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:amec="com.amec.Components.*"
horizontalCenter="true">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
[Bindable]
protected var textValue:String;
protected function control_creationCompleteHandler(event:FlexEvent):void
{
// todo: get control data from view.data
}
protected function control_clickHandler(event:MouseEvent):void
{
parentView.navigator.pushView(TextListView);
}
]]>
</fx:Script>
<s:Label text="Robert says something meaningful goes here" />
<s:TextInput id="ns" text="{textValue}" editable="false" click="control_clickHandler(event)"/>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
Again I cannot use pushView as the view is already on the stack.
In case you want to do it the right way, on the previous view (the one you want the result going to, add an eventListener for 'add'.
protected function addHandler(event:FlexEvent) : void {
if (navigator.poppedViewReturnedObject != null) {
var returnedObject : Array = navigator.poppedViewReturnedObject.object as Array;
if(!returnedObject) return;
yourData= new ArrayCollection(returnedObject);
}
}
On the view that you are going to pass the object from:
override public function createReturnObject():Object {
var returnedObject : Object = new Object();
returnedObject = dataYouWantToSendBack;
return returnedObject;
}
I looked at using static variables but that was a little messy, I also looked at using Dependency Injection but spending a few hours to set up the framework and get it running is to costly when all I am doing is passing parameters on a popView, so what I came up with is the similar approach I have used when doing Native Android Apps with the Android SDK. A Singleton with getters and setters.
Basically the way I have been able to do this is with the use of a Singleton sharedInstance. See code below:
package com.controls.Text
{
import flash.utils.Dictionary;
[Bindable]
public class ParameterManager
{
private static var instance:ParameterManager = new ParameterManager();
private var dictionary:Dictionary=new Dictionary();
public function ParameterManager( )
{
if (instance != null) { throw new Error('Must use ParameterManager.getInstance().') }
}
public static function getInstance(): ParameterManager {
return instance;
}
public function setParameter(key:*, value:*):void
{
dictionary[key]=value;
}
public function getParameter(key:*):*
{
return dictionary[key];
}
}
}
The method setting the value of the parameter:
protected function myList_changeHandler(event:IndexChangeEvent):void
{
var listViewReturnObject:String = new String();
listViewReturnObject = list.selectedItem.DMV_VALUE_1;
ParameterManager.getInstance().setParameter("selectedItem", listViewReturnObject);
navigator.popView();
}
The method getting the value:
protected function control_creationCompleteHandler(event:FlexEvent):void
{
var listViewReturnObject:Object = new Object();
listViewReturnObject= ParameterManager.getInstance().getParameter("selectedItem");
if (listViewReturnObject != null)
{
dataTxt.text= String(listViewReturnObject);
ParameterManager.getInstance().setParameter("", null); //Make sure objects are cleared when done.
}
}

get component variables values into main application

i have a component which gets the data selected by the radio button
<mx:itemRenderer >
<fx:Component id="radio">
<mx:RadioButton selected="false" useHandCursor="true" change="item_changeHandler(event)">
<fx:Script>
<![CDATA[
private var data_id:int;
private var data_name:String;
protected function item_changeHandler(event:Event):void
{
data_id=data.id;
data_name=data.name;
}
]]>
</fx:Script>
</mx:RadioButton>
</fx:Component>
</mx:itemRenderer>
here there are 2 variables data_id and data_name and i want to use this component variables in the main application which get called when i click a button so what to do how do i call the variables values into this function i tried this
protected function delete_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
dispatchEvent( new Event( Event.CHANGE ) );
deleteTaxonomy(data.id, data.name);
}
If I understand you correctly, then I would dispatch an event when the id and name changes and catch it in the main application. E.g. you could create a CustomEvent class YouDataEvent.as with the variables id and name. I often use this with my own objects and then send the object with the event. Lets call your object containing the id and name YourObject
import flash.events.Event;
public class YourObjectEvent extends Event
{
public static const YOURDATA_UPDATED:String = "yourdataUpdated";
public var yourObj:YourObject
public function YourObjectEvent(type:String, yourObjInput:YourObject, bubbles:Boolean = true, cancelable:Boolean = false)
{
this.yourObj = yourObjInput;
super(type, bubbles, cancelable);
}
}
Then you can dispatch the event when the data changes e.g. in the *item_changeHandler* method like so:
dispatchEvent(new YourObjectEvent(YourObjectEvent.YOURDATA_UPDATED, yourObjVar));
And catch it at the main application with e.g.:
FlexGlobals.topLevelApplication.addEventListener(YourObjectEvent.YOURDATA_UPDATED, yourObjUpdatedHandler);
private function yourObjUpdatedHandler(event:YourObjectEvent): void {
//DO something
var id:Number = event.yourObj.id;
var name:String = event.yourObj.name
}
Hope this helps!

Two way databinding for combobox's selectedItem is not working via # symbol in Adobe Flex 4

I need to enable two way data binding in combobox’s selectedItem and a valueobject’s one of the field. I am using #{variable name} construct.
It works one way - when valueobject’s field is changed, combobox’s selectedItem is getting updated.
But reverse is not working unless I handle combobox’s change event explicitly.
Is there any reason for # not working as per expectation.
In below code snippet, I am trying to bind OrderInfo.billingName to combo1.selectedItem.
1st use case : OrderInfo.billingName’s initial value is getting set to combo1.selectedItem
2nd use case: In case OrderInfo.billingName value is changed in between, then also combo1.selectedItem is getting updated
3rd use case : When user select some value from combo1, it is not getting assigned to OrderInfo.billingName unless I handle change event.
[Bindable]
public class OrderInfo {
public var billingName:String ; //This field is bindable to combo1’s selectedItem
public var billingAddress:String;
public var billingCity:String;
public var billingState:String;
public var billingZip:String;
public var cardType:String;
public var cardNumber:String;
public var cardExpirationMonth:String;
public var cardExpirationYear:String;
public var deliveryDate:Date;
public function OrderInfo() {
}
public function toString ():String {
return "I am OrderInfo : " + this.billingName + this.billingCity;
}
}
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955"
minHeight="600"
initialize="application1_initializeHandler(event)">
<fx:Script>
<![CDATA[
import mx.binding.utils.BindingUtils;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.events.FlexEvent;
import mx.events.IndexChangedEvent;
import mx.utils.ObjectUtil;
import spark.events.IndexChangeEvent;
[Bindable]
public var dp:ArrayCollection = new ArrayCollection (
[ {Id:'one', Amount:1000},
{Id:'two', Amount:2000},
{Id:'three', Amount:3000}
]
);
[Bindable]
public var orderInfo:OrderInfo = new OrderInfo();
protected function application1_initializeHandler(event:FlexEvent):void
{
//Initial value of the field .. this could be coming via database
orderInfo.billingName = 'one';
}
protected function combo1_changeHandler(event:IndexChangeEvent):void
{
orderInfo.billingName = (((event.currentTarget as
ComboBox).selectedItem as Object).Id); //??
}
protected function button1_clickHandler(event:Event):void
{
mx.controls.Alert.show(ObjectUtil.toString(orderInfo));
}
protected function button2_clickHandler(event:Event):void
{
// Some backend process changed the value object
orderInfo.billingName = 'three';
}
]]>
</fx:Script>
<s:ComboBox id="combo1" x="81" y="65"
dataProvider="{dp}"
labelField="Id"
selectedItem="#{orderInfo.billingName}"
change="combo1_changeHandler(event)"
/>
<s:Button label="Get OrderInfo Object Snapshot" click="button1_clickHandler(event)"
x="273" y="176"/>
<s:Button label="Change OrderInfo Object" click="button2_clickHandler(event)"
x="52" y="176"/>
I am also looking into getting this functionality working. I believe the issue lies in what is being bound. The selectedItem property expects an object of type * which means an item from the arrayCollection that it's bound with. So try passing one or these objects
({Id:'one', Amount:1000},{Id:'two', Amount:2000},{Id:'three', Amount:3000})
to the selectedItem property instead of a string.

Flex Binding : Unexpected behaviour

I have noticed an unexpected behaviour with binding in Flex, my code is as follow :
Application code
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" horizontalAlign="center" xmlns:Model="Model.*">
<mx:Script>
<![CDATA[
import Model.DataDummy;
]]>
</mx:Script>
<mx:HBox width="100%" horizontalGap="30">
<mx:Button id="buttonChange1" label="Change property value" click="myDummy._resetMyProperty();" />
<mx:Label id="labelRaw" text="{'My Property=' + myDummy.MyProperty}" opaqueBackground="#DDDDDD" />
<mx:Label id="labelFormatted" text="{'My Property formatted=' + myDummy.MyPropertyFormatted}" opaqueBackground="#DDDDDD" />
</mx:HBox>
<Model:MyDummy id="myDummy" />
<mx:DataGrid id="dataGrid"
width="100%" dataProvider="{DataDummy.Dummies}">
<mx:columns>
<mx:DataGridColumn dataField="MyProperty" headerText="My property" />
<mx:DataGridColumn dataField="MyPropertyFormatted" headerText="My property Formatted" />
</mx:columns>
</mx:DataGrid>
<mx:Button id="buttonChange2" click="{for each ( var d:MyDummy in DataDummy.Dummies ){d._resetMyProperty();}}" label="Change property value in DataGrid" />
</mx:Application>
Model.MyDummy class code
package Model
{
import flash.events.EventDispatcher;
import mx.formatters.NumberFormatter;
import mx.utils.StringUtil;
[Bindable]
public class MyDummy extends EventDispatcher
{
/*** Constructor ***/
public function MyDummy()
{
this._resetMyProperty();
}
/*** Properties ***/
private var _myProperty:Number;
public function get MyProperty():Number
{
return _myProperty;
}
public function set MyProperty(value:Number):void
{
if ( value !== _myProperty )
{
_myProperty = value;
//var event:Event = new Event("ID_Changed");
//this.dispatchEvent(event);
}
}
//[Bindable (event="ID_Changed", type="flash.events.Event")]
public function get MyPropertyFormatted():String
{
var idFormatted:String = "";
if ( ! isNaN(this.MyProperty) )
{
var formatter:NumberFormatter = new NumberFormatter();
formatter.precision = 2;
idFormatted = formatter.format(this.MyProperty);
}
else
idFormatted = MyProperty.toString();
return StringUtil.substitute( "{0} (My property has been formatted)", idFormatted );
}
/*** Methods ***/
public function _resetMyProperty():void
{
this.MyProperty = Math.round(Math.random() * 1000000000);
}
}
}
Model.DataDummy class code
package Model
{
import mx.collections.ArrayCollection;
public class DataDummy
{
private static var _dummies:ArrayCollection;
public static function get Dummies():ArrayCollection
{
if ( _dummies == null )
{
_dummies = new ArrayCollection();
_dummies.addItem(new MyDummy());
_dummies.addItem(new MyDummy());
}
return _dummies;
}
}
}
The behaviour is as follow :
When I click on buttonChange1, _resetMyProperty is called on the instance myDummy.
The result is that the label "labelRaw" has its text changed and the label "labelFormatted" does not have its text changed. This does happen because MyPropertyFormatted is a readonly property and that readonly properties are binded only at the initialisation of the application and not afterwards, according to Flex documentation. With this, I agree.
When I click on buttonChange2, resetMyProperty method is called on every MyDummy element of the ArrayCollection Model.DataDummy.Dummies (this static property is binded to the DataGrid).
The result is that both columns of the DataGrid have their values changed, despite the fact that the DataGrid's second column is linked to the same readonly property MyPropertyFormatted of the MyDummy objects. I find this inconsistent with the previous behaviour I described.
My point is that :
1. On one hand, because I'm binding my controls to a single instance of an certain object, binding won't trigger on his readonly properties.
2. On the other hand, when I'm binding a control on a collection of the same certain objects, binding will trigger on every properties (readonly or not).
If I want binding to be triggered on readonly properties in point 1, I have to dispatch an event and precise on the readonly properties' MetaTag that their binding will be triggered according to this event (as show the commentaries in the code of the class Model.MyDummy class).
Why is this behaviour different ? I would like to precisely understand what an ArrayCollection instance's binding does that a single instance's binding does not.
Thank you for your help.
I suppose the right code is something like the following.
First, our model.MyDummy class:
package model
{
import flash.events.EventDispatcher;
import mx.events.PropertyChangeEvent;
import mx.formatters.NumberFormatter;
import mx.utils.StringUtil;
public class MyDummy extends EventDispatcher
{
//------------------------------------------------------------------------------
//
// Constructor
//
//------------------------------------------------------------------------------
public function MyDummy()
{
resetMyProperty();
}
//------------------------------------------------------------------------------
//
// Properties
//
//------------------------------------------------------------------------------
//--------------------------------------
// myProperty
//--------------------------------------
private var _myProperty:Number;
[Bindable(event="propertyChange")]
public function get myProperty():Number
{
return _myProperty;
}
public function set myProperty(value:Number):void
{
if (_myProperty == value)
return;
var oldPropertyValue:Number = _myProperty;
var oldFormatted:String = myPropertyFormatted;
_myProperty = value;
dispatchEvent(PropertyChangeEvent.createUpdateEvent(this, "myProperty", oldPropertyValue, value));
dispatchEvent(PropertyChangeEvent.
createUpdateEvent(this, "myPropertyFormatted", oldFormatted, myPropertyFormatted));
}
[Bindable(event="propertyChange")]
public function get myPropertyFormatted():String
{
var idFormatted:String = "";
if (!isNaN(myProperty))
{
var formatter:NumberFormatter = new NumberFormatter();
formatter.precision = 2;
idFormatted = formatter.format(myProperty);
}
else
idFormatted = myProperty.toString();
return StringUtil.substitute("{0} (My property has been formatted)", idFormatted);
}
//------------------------------------------------------------------------------
//
// Methods
//
//------------------------------------------------------------------------------
public function resetMyProperty():void
{
myProperty = Math.round(Math.random() * 1000000000);
}
}
}
We're firing propertyChange event to have possibility to fire collectionChangeEvent from our ArrayCollection (it listens propertyChange event automatically).
Then our model.DataDummy class:
package model
{
import mx.collections.ArrayCollection;
import mx.events.CollectionEvent;
public class DataDummy
{
//------------------------------------------------------------------------------
//
// Constructor
//
//------------------------------------------------------------------------------
public function DataDummy()
{
dummies = new ArrayCollection();
dummies.addItem(new MyDummy());
dummies.addItem(new MyDummy());
}
//------------------------------------------------------------------------------
//
// Variables
//
//------------------------------------------------------------------------------
[Bindable]
public var dummies:ArrayCollection;
}
}
We don't use statics to have advantage of data binding with [Bindable] metatag.
And finally our main class with minimal changes:
<mx:Application horizontalAlign="center" layout="vertical" xmlns:model="model.*" xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
//------------------------------------------------------------------------------
//
// Event Handlers
//
//------------------------------------------------------------------------------
protected function buttonChange2_clickHandler(event:MouseEvent):void
{
for each (var d:MyDummy in dataProvider.dummies)
{
d.resetMyProperty();
}
}
]]>
</mx:Script>
<mx:HBox horizontalGap="30" width="100%">
<mx:Button click="myDummy.resetMyProperty();" id="buttonChange1" label="Change property value" />
<mx:Label id="labelRaw" opaqueBackground="#DDDDDD" text="{'My Property=' + myDummy.myProperty}" />
<mx:Label id="labelFormatted" opaqueBackground="#DDDDDD"
text="{'My Property formatted=' + myDummy.myPropertyFormatted}" />
</mx:HBox>
<model:MyDummy id="myDummy" />
<model:DataDummy id="dataProvider" />
<mx:DataGrid dataProvider="{dataProvider.dummies}" id="dataGrid" width="100%">
<mx:columns>
<mx:DataGridColumn dataField="myProperty" headerText="My property" />
<mx:DataGridColumn dataField="myPropertyFormatted" headerText="My property Formatted" />
</mx:columns>
</mx:DataGrid>
<mx:Button click="buttonChange2_clickHandler(event)" id="buttonChange2" label="Change property value in DataGrid" />
</mx:Application>
As you can see all the bindings works as expected.
P.S. [Bindable(event="propertyChange")] is an equivalent of simple [Bindable] but this way you can avoid compiler warnings on myPropertyFormatted getter. Actually, using simple [Bindable] form causes mxmlc compiler to generate dispatchEvent code by itself. And you can use pointing a particular event in [Bindable] tag to have more control. For example in our case we can fire event for myPropertyFormatted.
P.P.S. I've changed your C#-like naming conventions to reflect actual ActionScript/MXML ones.

Fundamental binding issue

I just ran into a strange binding problem. In the mini app below, the Flex Label component is updated when 'someText' changes, but my boundSetter won't be called after the first, initial call.
In short: Why is the boundSetterForSomeText() function not called, while the label does update?
Could anybody please shed some light onto this fundamental issue? Thanks a million!
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" minWidth="1024" minHeight="768"
initialize="onInitialize()"
>
<mx:Panel>
<mx:Label text="{this.someText}" />
<mx:Button label="Set random text" click="generateRandom()" />
</mx:Panel>
<mx:Script>
<![CDATA[
import mx.binding.utils.ChangeWatcher;
import mx.binding.utils.BindingUtils;
[Bindable(event="xxx")]
public var someText : String;
public function onInitialize() : void
{
var cw:ChangeWatcher = BindingUtils.bindSetter(boundSetterForSomeText, this, ['someText']);
}
public function generateRandom() : void
{
this.someText = String( Math.round(Math.random() * 10000) );
this.dispatchEvent(new Event("xxx"));
}
public function boundSetterForSomeText(obj:Object) : void
{
trace( obj );
}
]]>
</mx:Script>
</mx:Application>
You can use this code to create a get/set pair or "property":
private var _someText:String;
[Bindable(event="xxx")]
public function get someText():String
{
return _someText;
}
public function set someText(value:String):void
{
if (_someText != value)
{
_someText = value;
this.dispatchEvent(new Event("xxx"));
}
}
It does work when event is default. (Default event is propertyChange)
[Bindable]
public var someText : String;
I did some debugging and I have no clue why it doesn't work with custom event. I think it should.

Resources