flex 4.6 : Pass Objects between views using actionscript 3 - actionscript-3

I using flex 4.6 to build mobile application. i want to pass objects between views. i use in the first view
User.name = Username.text;
User.Pass = Password.text;
navigator.pushView(views.masterHomeView , User)
and in the second view
<s:Label id="b" text="{data.name}"/>
<s:Label id="lbl" text="{data.Pass}" />
and it worked well for represent the data in the labels , but i want to review the object in the action script not in mxml to pass values of object to function
Thanks in advance

The problem solved by using
override public function set data(value:Object):void
{
var x = value.name;
var y = value.Pass;
}

Related

accessing current rowData of dataprovider in flex view

I have a view
<view:SampleDataGridView
rowCount="{Math.min(MAX_ROW_COUNT, hostComponent.dataList.length)}"
dataprovider="{hostComponent.dataList}"
buttonMode="true"
click="clickRow(event)"
/>
I want to get which row was clicked. I tried using currentTarget and target from event object however it wasn't of much use.
Is there a way I can pass some parameter in clickEvent function like clickEvent(rowData) or clickEvent(currentRowIndex)?
Is there any property when we use dataProvider to show currentIndex?
Data Grid
<mx:DataGrid id="employeeDataGrid" doubleClickEnabled="true" itemDoubleClick="selectEmployee(event);" dataProvider={employeeList} >
Handler
protected function selectEmployee(event:ListEvent):void
{
var selectedEmployee:Employee = event.currentTarget.selectedItem as Employee;
}

Flex Datagrid labelFunction query

Main.mxl
<s:DataGrid dataProvider="{employeeData}"> // employeeData is an Arraycollection with predefined data
<s:typicalItem>
<s:DataItem firstName="Christopher"
lastName="Winchester"
hireDate="22/12/2013"/>
</s:typicalItem>
<s:columns>
<s:ArrayList>
<s:GridColumn labelFunction="employeeName"
headerText="Name"/>
<s:GridColumn dataField="hireDate"
headerText="Hire Date"
labelFunction="dateFormat"/>
</s:ArrayList>
</s:columns>
</s:DataGrid>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.dataGridClasses.DataGridColumn;
import mx.rpc.events.ResultEvent;
[Bindable]
private var employeeData: ArrayCollection;
private function employeeName(item: Object, column: GridColumn): String
{
return item.firstName+" "+item.lastName;
}
]]>
</fx:Script>
A) Can anyone please explain me how does Datagrid internally works with employeeName function? I mean, Iam not even passing 2 parameters for labelFunction, BUT still how does it get called?
B) Why should I use s:ArrayList tag inside s:columns tag?
A) Can anyone please explain me how does Datagrid internally works
with employeeName function? I mean, Iam not even passing 2 parameters
for labelFunction, BUT still how does it get called?
The labelFunction is a property on the GridColumn class. Inside the Gridcolumn there is an itemToString() function which is used to determine what the label should be for that specific instance of the column. right out of the framework code:
/**
* #private
* Common logic for itemToLabel(), itemToDataTip(). Logically this code is
* similar to (not the same as) LabelUtil.itemToLabel().
*/
private function itemToString(item:Object, labelPath:Array, labelFunction:Function, formatter:IFormatter):String
{
if (!item)
return ERROR_TEXT;
if (labelFunction != null)
return labelFunction(item, this);
var itemString:String = null;
try
{
var itemData:Object = item;
for each (var pathElement:String in labelPath)
itemData = itemData[pathElement];
if ((itemData != null) && (labelPath.length > 0))
itemString = (formatter) ? formatter.format(itemData) : itemData.toString();
}
catch(ignored:Error)
{
}
return (itemString != null) ? itemString : ERROR_TEXT;
}
B) Why should I use s:ArrayList tag inside s:columns tag?
Because the data type of the columns property on the DataGrid is an IList; and the ArrayList implements the IList interface. What you're looking at is the MXML way to create and define an ArrayList. You'd use a slightly different approach if you wanted to create the columns in ActionScript.
To answer your first question: the "labelFunction" property is a reference to the function that will be invoked by the DataGrid to format the text of a cell in a column. The function will be called dynamically and the DataGrid will pass in the required parameters. The DataGrid expects a label function to always have this signature. If you fail to do so, you will get a runtime error.
Technically, a function can be called dynamically with the following syntax:
var anObject:MyType;
var methodName:String = "myMethod";
anObject[methodName](param1, param2);
or if you have a Function object
var myFunction:Function;
myFunction(param1, param2);

Flex getElementByName

I know that there is no such function as getElementByName in Flex but I also now that you can do this["object_id"] to get the element of the application u're in.
What about getting an element inside another element?
I've tried making element["id"] ? But in my try-catch it always runs the "catch" part =\
So: how do I get an element inside another element just having it's id in dynamically created string form?
Thank you in advance
It depends on what kind of element you are trying to access.
A child display object can be accessed by calling DisplayObjectContainer#getChildByName:
element.getChildByName("name");
A public variable (which could be set to also contain a child display object) can be accessed by using bracket syntax:
element["name"];
or simply using dot syntax:element.name
(where name is the name of the property you are trying to access).
Note that any instance you drag to the stage in the Flash IDE will automatically be assigned to a public variable, if you have the "automatically declare stage instances" option checked in your export settings. That is why using this[name]works.
If I understand correctly, you're asking for a way to get all the "elements" in a Flex application that have a certain name.
Here's an example (Flex 3):
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*">
<mx:Script>
<![CDATA[
private function testIt():void
{
var arr:Array = getDisplayObjectsByName(this, "foo");
for each (var e:* in arr)
trace(e);
}
private static function getDisplayObjectsByName(node:DisplayObjectContainer,
name:String, recurse:Boolean = true):Array
{
var n:int = node.numChildren;
var a:Array = [];
for (var i:int = 0; i < n; i++) {
var c:DisplayObject = node.getChildAt(i);
if (c.name == name)
a.push(c);
if (recurse) {
if (c is DisplayObjectContainer)
a = a.concat(getDisplayObjectsByName(DisplayObjectContainer(c),
name, true));
}
}
return a;
}
]]>
</mx:Script>
<mx:VBox name="foo">
<mx:HBox>
<mx:Button name="foo" label="Test" click="testIt()" />
</mx:HBox>
</mx:VBox>
<mx:Label text="Ignore Me" />
<mx:VBox name="bar">
</mx:VBox>
</mx:Application>
Here we're looking for all the elements called "foo" when the user clicks the "Test" button.
Output:
main0.foo
main0.foo.HBox5.foo
You'll notice that getDisplayObjectsByName() is static. All it does is traverse the display list (depth-first) and pick out all the objects with the specified name.
If you're looking for the element in a Group, you can use this function:
static function getElementByName(group:GroupBase, name:String):IVisualElement {
const child:DisplayObject = group.getChildByName(name);
const index:int = group.getChildIndex(child);
return group.getElementAt(index);
}

How to show list of components in Flex

I'm building a multiplayer game which when connecting to the server, the server sends back a list of available rooms (each room has MaxPlayers,MinRank,TableId,TableName,Password) so everytime I recieve these 5 strings, I create an instance of Mxml UI Component I have created and fill it with the relevant details.
In the main.MXML i've added an AS3 script variable to hold the GameInstances object i've created when rcvd data back from the server:
private var gameInstances:ArrayCollection = new ArrayCollection();
GameInstance.mxml is a component that has UI components in it and AS3 script to set some data.
When rcving data from the server in main.mxml :
var gameInstance:GameInstance = new GameInstance();
gameInstance.setTablePlayers(rcvdMsg[1]);
gameInstance.setTableMinRank(rcvdMsg[2]);
gameInstance.setTableId(rcvdMsg[3]);
gameInstance.setTableName(rcvdMsg[4]);
gameInstance.setTablePassword(rcvdMsg[5]);
gameInstances.addItem(gameInstance);
gameInstances holds objects of that mxml component.
How do I show this component visualy on the main.mxml?
I have a in main.mxml that I want visually show inside it the GameInstance objects.
This is how GameInstance.mxml looks like, I want the s:List to hold for each game a UI object like that(to show it ofcourse)
OK, if you using the gameInstances arraycollection as a data provider for tableList then you need to do a few things.
First, you need to make your gameInstances arraycollection [Bindable]
Then, you need to add data to the array collection as code you posted shows you are.
Next, you have to Create a custom item renderer for your tableList.
Finally, when you are done changing data/adding/removing objects from the gameInstances arraycollection you need to gameInstances.refresh();
[EDIT]
create a file named myListRenderer.mxml and put this code in it
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
override protected function commitProperties():void{
// this is where you assign your values
// this function gets called every-time the list scrolls
super.commitProperties();
players.text = this.data.setTablePlayers
minRank.text = this.data.setTableMinRank;
tableId.text = this.data.setTableId;
tableName.text = this.data.setTableName;
tablePassword.text = this.data.setTablePassword;
}
]]>
</mx:Script>
<mx:Label id="players" />
<mx:Label id="minRank" />
<mx:Label id="tableId" />
<mx:Label id="tableName" />
<mx:Label id="tablePassword" />
</mx:VBox>
If I understand the question, when you create components in ActionScript, you have to add them to a container before they'lls how up in the UI. If you have an array of components, you can just loop over that array and add each component as a child on a container. The main application file is a container, so you can do something like this:
for each(var myComp:UIComponent in myArrayList){
addChild(myComp);
}
It would be unusual to take this approach. Usually you just add the component to the parent container as you create them.

Creating Dynamically Flex Custom ItemRender (Constructor)

am creating some Advanced Datagrid with actionscript.
I have created an actionscript class where I extend the VBox object:
package core
{
import mx.containers.VBox;
import mx.controls.TextInput;
public class customItemRender extends VBox
{
public function customItemRender(_TextInput:TextInput, _TextInput2:TextInput)
{
//TODO: implement function
super.addChild(_TextInput);
super.addChild(_TextInput2);
}
}
}
The problem comes up when I declare de itemrender property on the data grid:
AdvancedDataGridColumn.itemRenderer = new ClassFactory(customItemRender(_TextInput1,_TextInput2));
The compiler wont let me instanciate my customItemRender.
Does any one know if there is an alternative solution to solve the problem?
Thanks in advance for you helps,
Regards Javier
private var _ItemRendere:ClassFactory;
private function get MyItemRendere():ClassFactory
{
if (_ItemRendere == null)
{
_ItemRendere = new ClassFactory();
_ItemRendere.generator = customItemRender;
_ItemRendere.properties = {
_TextInput1:MY_TextInput1_OBJECT,
_TextInput2:MY_TextInput2_OBJECT
};
}
return _ItemRendere;
}
then you can use
AdvancedDataGridColumn.itemRenderer = MyItemRendere;
I've only tried to do this using MXML. In that case, i usually have to wrap the IListItemRenderer instance in mx:Component tags. I'm not exactly sure what is going on programmatically when I do this, but it works. The reason is that the itemRender is actually looking for an instance of IFactory rather than an instance so I suppose to do this strictly using AS you would need to create your own IFactory implementation.
e.g.
<mx:List>
<mx:itemRenderer>
<mx:Component>
<mx:Text />
</mx:Component>
</mx:itemRenderer>
</mx:List>
ClassFactory's constructor has a Class as a parameter, not an instance. You need to call:
new ClassFactory(customItemRender);
and not:
new ClassFactory(new customItemRender(_TextInput1,_TextInput2));
or:
new ClassFactory(customItemRender(_TextInput1,_TextInput2));
Now, since the constructor will not be called with reference to TextInput1 and TextInput2, you'll need to instantiate your own TextInputs in the custom renderer itself. (But this is a good thing, if you continue to call new customItemRender(_TextInput1, _TextInput2), then the two TextInputs will only be added to the LAST instance of customItemRender, and all of the others will not have these two objects ).