Passing a parameter from flex main to a flex(4) component with data binding - apache-flex

I have a main mxml file (flex4) and want to pass a parameter (user_name) to a component in a directory called components.
When I run the program, the user_name is NOT being sent from the main to the component file.
(Interestingly, if you make the component visible, you can see the parameter has been passed)
New to flex/actionscript and this parameter passing is (without help) quite a pain to progress.
So, help would be very much appreciated.
TIA.
I have hacked much larger files down to get the following two files:
MAIN
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:components="components.*">
<mx:Button id="editAccount" label="Edit Account" fontSize="16" color="#000000" x="100" y="125" click="AccountForm(event)" />
<components:editAccountForm visible="false" user_name = "username from main" />
<fx:Script>
<![CDATA[
import components.editAccountForm;
import mx.managers.PopUpManager;
private function AccountForm(e:MouseEvent):void
{
var win3:editAccountForm = new editAccountForm();
PopUpManager.addPopUp(win3,this,true);
PopUpManager.centerPopUp(win3);
}
]]>
</fx:Script>
</s:Application>
COMPONENT FILE
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" title="Edit Account Details" x="50" y="600" >
<mx:Form width="100%" height="100%">
<mx:FormItem label="">
<mx:Label width="300" textAlign="center" text="{user_name}"/>
</mx:FormItem>
<mx:FormItem label="Enter your new Email Address">
<mx:TextInput id="email_address2" width="300" maxChars="128" contentBackgroundColor="#F5DC0C"/>
</mx:FormItem>
</mx:Form>
<mx:HBox width="100%" horizontalAlign="center">
<mx:Button id="close" label="Close" click="PopUpManager.removePopUp(this)" />
</mx:HBox>
<mx:Script>
<![CDATA[
[Bindable]
public var user_name:String = "username from Component";
]]>
</mx:Script>
<mx:Script>
<![CDATA[
import mx.core.IFlexDisplayObject;
import mx.events.CloseEvent;
import mx.managers.PopUpManager;
private function closeWindow(e:CloseEvent):void
{
PopUpManager.removePopUp(e.target as IFlexDisplayObject);
}
]]>
</mx:Script>
</mx:TitleWindow>

If you simply want to get the user_name from the main app into your TitleWindow component, just set win3.user_name = user_name after you instantiate win3. If you are looking to bind it to your newly instantiated win3 (which you would do if user_name were expected to change), then you need to look into the BindUtils helper class.
The typical way of getting data back and forth between an app and a dialog is to set the value after you instantiate your dialog, and then add a listener to your dialog so that your app will get notified if something changed. If you are listening for the Close event, for example, you can get the value from the event like so: (event.currentTarget as EditAccountForm).user_name in your app's event handler.
Another common method is to have your window dispatch a custom event (that your main app added a listener to the dialog for) which contains the new value for user_name.
Hope that helps.

Related

How to access MXML component instance in ItemRenderer

I have been developing an Adobe Flex (v3.5 Flex SDK) based application and I have a question on How we can access (call) a method written in MXML file (embeded in script tag) from the ItemRenderer file.
The MXML component has a datagrid and for one of the columns, the itemrenderer is my own custom item renderer.
In my custom item renderer, for some event I need to call a method which exist in its parent MXML component. How do we get access to its parent MXML instance ?
I have explored for this in google and found that we can access to 'data' object which refers to the dataProvider of the datagrid. But I wanted access to the instance of MXML component (so that I can call a method in it) which has the datagrid.
The AdvancedDataGridColumn in AdvancedDataGrid is like this
<mx:AdvancedDataGridColumn dataField="total" headerText="Total" width="120" itemRenderer="renderers.MyItemRenderer"/>
Here MyItemRenderer is a separate action script file.
Appreciate the response.
Thanks
Raagu
As Raghavendra Nilekani suggested This works:
TestGrid.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="955" minHeight="600">
<fx:Script>
<![CDATA[
[Bindable]
public var data:Array = [
{name:"name",value:"valeu1",timestamp:"423423"},
{name:"name1",value:"valeu2",timestamp:"423423"},
{name:"name2",value:"valeu3",timestamp:"423423"},
{name:"name3",value:"valeu5",timestamp:"423423"}
]
public function calculateValue():Number{
return Math.random();
}
]]>
</fx:Script>
<fx:Declarations>
</fx:Declarations>
<mx:VBox height="100%" width="100%">
<mx:AdvancedDataGrid dataProvider="{data}">
<mx:columns>
<mx:AdvancedDataGridColumn itemRenderer="ItemRenderer">
</mx:AdvancedDataGridColumn>
</mx:columns>
</mx:AdvancedDataGrid>
</mx:VBox>
</s:Application>
e ItemRendere.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:MXAdvancedDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
focusEnabled="true"
addedToStage="mxadvanceddatagriditemrenderer1_addedToStageHandler(event)"
>
<fx:Script>
<![CDATA[
[Bindable]
var value:Number;
import mx.containers.VBox;
import mx.controls.AdvancedDataGrid;
protected function mxadvanceddatagriditemrenderer1_addedToStageHandler(event:Event):void
{
var grid:AdvancedDataGrid = ((AdvancedDataGrid)(this.owner));
var box:VBox = ((VBox)(grid.owner))
var comp:TestGrid = (TestGrid)(box.owner);
value = comp.calculateValue();
}
]]>
</fx:Script>
<s:Label id="lblData" top="0" left="0" right="0" bottom="0" text="{value}" />
</s:MXAdvancedDataGridItemRenderer>
Anyway I agree with zenbeni that this lead to a not reausable item renderer.

How do I use data from the main window in a sub-window?

I've just started working on a photo viewer type desktop AIR app with Flex. From the main window I can launch sub-windows, but in these sub-windows I can't seem to access the data I collected in the main window.
How can I access this data?
Or, how can I send this data to the sub-window on creation? It doesn't need to be dynamically linked.
myMain.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="260" height="200"
title="myMain">
<fx:Declarations>
</fx:Declarations>
<fx:Script>
<![CDATA[
public function openWin():void {
new myWindow().open();
}
public var myData:Array = new Array('The Eiffel Tower','Paris','John Doe');
]]>
</fx:Script>
<s:Button x="10" y="10" width="240" label="open a sub-window" click="openWin();"/>
</s:WindowedApplication>
myWindow.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Window name="myWindow"
title="myWindow"
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
width="640" height="360">
<mx:Script>
<![CDATA[
]]>
</mx:Script>
<mx:Label id="comment" x="10" y="10" text=""/>
<mx:Label id="location" x="10" y="30" text=""/>
<mx:Label id="author" x="10" y="50" text=""/>
</mx:Window>
I realize this might be a very easy question but I have searched the web, read and watched tutorials on random AIR subjects for a few days and couldn't find it. The risk of looking like a fool is worth it now, I want to get on with my first app!
You could add an attribute to your window class, and pass the data from the application.
With an attribute and a setter function :
myWindow.mxml :
<![CDATA[
private var _data : Array;
public function set data(data : Array) : void {
this._data = data;
}
]]>
main
<![CDATA[
public function openWin():void {
var w : myWindow = new myWindow();
w.data = myData;
w.open();
}
public var myData:Array = new Array('The Eiffel Tower',
'Paris','John Doe');
]]>
You could also do it by adding a constructor parameter to your window, but you will have to write your Window component in ActionScript.
(Also : you might want to use MyWindow for the name of your component instead of myWindow, but that's just conventionnal nitpicking).
Also, note that there is a singleton variable Application.application that is accessible to all classes in an Application ; however I don't know if this applies to a WindowedApplication, and either way it is not the recommended approach.

child elements of MXML class not appearing

I'm working on a simple task/calendar tool where tasks can be added dynamically to a canvas. Here is the main application as defined in Main.mxml, which is essentially just a Canvas and a button for adding a task:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Canvas id="MainCanvas" borderStyle="solid" width="300" height="300">
<mx:Button click="CreateTask();" label="create task" />
</mx:Canvas>
<mx:Script>
<![CDATA[
import Task;
private function CreateTask( ) : void
{
// create the task object
var thisTask:Task = new Task();
// add the task to the canvas
var taskUI : DisplayObject = MainCanvas.addChild( thisTask );
// position the task ui
taskUI.y = 50;
}
]]>
</mx:Script>
</mx:Application>
I want my tasks to be BorderContainers with a label and a button, defined in an external mxml, that can simply be instantiated and added to the canvas in Main.mxml. Here is Tasks.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:s="library://ns.adobe.com/flex/spark" cornerRadius="10">
<s:layout>
<s:HorizontalLayout/>
</s:layout>
<s:Label id="NameLabel" text="task name" />
<s:Button label="Button 1"/>
</s:BorderContainer>
The problem is that when I add a Task instance to the Canvas, the children (the button and label) don't appear. I tried setting creationPolicy="all" on both the Canvas and the BorderContainer, but it still didn't work. I've read a bunch of posts about people having issues accessing members of their class before the class is fully loading, but all I want to do is SEE that Label and Button show up inside the BorderContainer.
Thanks.
You need to move off of the flex 3 mx namespace to the newer namespace if you want to mix mx and spark controls together.
Here's your main.mxml with the new mx namespace (library://ns.adobe.com/flex/mx), and the fx namespace added to handle the script block:
<?xml version="1.0" encoding="utf-8"?>
<mx: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" >
<fx:Script>
<![CDATA[
import Task;
private function CreateTask( ) : void
{
// create the task object
var thisTask:Task = new Task();
// add the task to the canvas
var taskUI : DisplayObject = MainCanvas.addChild( thisTask );
// position the task ui
taskUI.y = 50;
}
]]>
</fx:Script>
<mx:Canvas id="MainCanvas" borderStyle="solid" width="300" height="300">
<mx:Button click="CreateTask();" label="create task" />
</mx:Canvas>
</mx:Application>
Although as other people have commented, you could just move everything over to spark - if you do that, be sure to change the addChild call to addElement.
It appears that adding spark component to an mx:canvas never triggers the code necessary to create the spark component's children. Here is a workaround for you:
<?xml version = "1.0" encoding = "utf-8"?>
<s:BorderContainer
xmlns:mx = "http://www.adobe.com/2006/mxml"
xmlns:s = "library://ns.adobe.com/flex/spark"
cornerRadius = "10"
creationComplete = "{addElement(poorUseOfContainers)}">
<s:HGroup id = "poorUseOfContainers"
width = "100%" height = "100%">
<s:Label id = "NameLabel"
text = "task name" />
<s:Button label = "Button 1" />
</s:HGroup>
</s:BorderContainer>

How to call a mxml component from another mxml component in flex-edited

I need to call a component named "defectTracker.mxml" by clicking a link in another mxml component called "reviewComponent.mxml". How do I achieve that?
This is my reviewComponent.mxml code:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
width="100%" height="100%"
horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:Script>
<![CDATA[
private function defectTrackerLink(event:Event):void{
//call defectTracker
}
]]>
</mx:Script>
<mx:LinkButton label="Delete" textDecoration="underline" textRollOverColor="blue"/>
<mx:LinkButton label="Defect Tracker" textDecoration="underline" textRollOverColor="blue" click="defectTrackerLink(event)"/>
</mx:VBox>
Some one guide me.
Main.mxml:
<mx:Script>
<![CDATA[
private function subBtnBar(evt:ItemClickEvent):void{
switch (evt.label){
case "IQA/UAT":
this.bdyStack.selectedChild = screenIQA;
break;
case "EQA":
Alert.show("Yet To Design");
break;
case "Review Tracker":
this.bdyStack.selectedChild = reviewTracker;
break;
case "Defect Tracker":
this.bdyStack.selectedChild = defectTracker;
break;
default:
trace ("Neither a or b was selected")
}
}
]]>
</mx:Script>
<mx:ViewStack id="tabView" width="910" creationPolicy="all">
<mx:ToggleButtonBar horizontalGap="0" id="subTabBar"
itemClick="subBtnBar(event);" styleName="SubButtonBar"
hideEffect="{dissolveOut}" showEffect="{dissolveIn}">
<mx:dataProvider>
<mx:String>IQA/UAT</mx:String>
<mx:String>EQA</mx:String>
<mx:String>Review Tracker</mx:String>
<mx:String>Defect Tracker</mx:String>
<mx:String>Defect Configuration</mx:String>
<mx:String>Defect Export</mx:String>
<mx:String>Defect Import</mx:String>
</mx:dataProvider>
</mx:ToggleButtonBar>
</mx:ViewStack>
<mx:ViewStack id="bdyStack" width="910" height="80%">
<components:ScrIQA id="screenIQA"
hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
<components:scrWorkList id="screenWorkList"
hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
<components:DefectEntryVerification id="defectEntryVerification"
hideEffect="{dissolveOut}" showEffect="{dissolveIn}"
width="100%" height="100%"/>
<components:scrDefectResolutionAndCause id="defectResolutionnVerification"
hideEffect="{dissolveOut}" showEffect="{dissolveIn}"
width="100%" height="100%"/>
<components:reviewTracker id="reviewTracker"
hideEffect="{dissolveOut}" showEffect="{dissolveIn}"
width="100%" height="100%"/>
<components:defectTracker id="defectTracker"
hideEffect="{dissolveOut}" showEffect="{dissolveIn}"
width="100%" height="100%"/>
</mx:ViewStack>
The defect Tracker scren is already linked with the main mxml file. How to call the function in the reviewComponent file?
reviewComponent consist of 2 link buttons and it is a column entry of the reviewTracker.mxml file's datagrid. So when I click the link in the review component, I want the defectTracker screen to be called. Its already a child of the main.mxml file.
I tried creting an instance of the main file in the component, and changes the selected child to defect tracker, It shows an error saying:
Error #1009: Cannot access a property or method of a null object reference.
My modified reviewComponent.mxml code:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
width="100%" height="100%"
horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:Script>
<![CDATA[
private function defectTrackerLink(event:Event):void{
var main:Main=new Main();
main.bdyStack.selectedChild=main.defectTracker; }
]]>
</mx:Script>
<mx:LinkButton label="Delete" textDecoration="underline" textRollOverColor="blue"/>
<mx:LinkButton label="Defect Tracker" textDecoration="underline" textRollOverColor="blue" click="defectTrackerLink(event)"/>
</mx:VBox>
Please some one guide me in this? Should I call the item click event function of the Toggle button Bar? If so how to do It?
I would use a custom event that bubbles. You would dispatch it from the reviewComponent and it would be caught by the defectTracker.
Here are some good articles that tell you how to create a custom event and how to use it http://livedocs.adobe.com/flex/3/html/help.html?content=createevents_3.html
http://www.connatserdev.com/blog/?p=86
By calling, do you mean adding it to the VBox?
var dTracker:DefectTracker = new DefectTracker();
addChild(dTracker);
Would calling is with a popup work?
var dTracker:DefectTracker = new DefectTracker();
PopUpManager.addPopUp(dTracker, this, true);

How content dynamically updated in flex

i need your help about below purposes.
problem-1:In php we can easily move one page to another and easily use different type of function from those pages.In flex3 how i can use different type of .mxml pages like php. Please guide me with tutorials.It will really helpful for me.
problem-2: In same page some content dynamically updated its resource by done one task.How can i do that please guide me.
Rather than treating your Flex application as a series of pages, you may want to consider an all-in-one SWF instead. This greatly reduces navigation time, at the cost of a longer initial download. You can switch among different views using tab pages or view stacks. As far as keeping your functions for each page separate, you can do this by implementing each logical "page" as a separate MXML component. Your top-level application MXML would look something like this:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:my="com.mycompany.myapp"
>
<mx:ViewStack id="pageViewStack" width="100%" height="100%">
<my:MyComponent1 width="100%" height="100%"/>
<my:MyComponent2 width="100%" height="100%"/>
</mx:ViewStack>
</mx:Application>
For your second problem I have 2 files
imageResize.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
private var _imageHolderWidth:Number = 500;
private var _imageHolderHeight:Number = 500;
[Bindable]
private var imageArrayCollection:ArrayCollection = new ArrayCollection();
private function changeSize():void{
this.imageHolder.width = this._imageHolderWidth *(this.widthSlider.value * 0.01);
this.imageHolder.height = this.imageHolder.width;
}
private function addToTileList():void{
var bitmapData : BitmapData = new BitmapData(this.imageHolder.width, this.imageHolder.height );
var m : Matrix = new Matrix();
bitmapData.draw( this.imageHolder, m );
this.imageArrayCollection.addItem({bitmapData: bitmapData, width: this.imageHolder.width, height: this.imageHolder.height});
}
]]>
</mx:Script>
<mx:Image id="imageHolder" source="#Embed('fx.png')" />
<mx:HSlider id="widthSlider" width="400" y="520" maximum="100" value="100" minimum="1" labels="[1%, 50%, 100%]" snapInterval="1" change="{changeSize();}" liveDragging="true" />
<mx:Button label="add to tile" click="{this.addToTileList();}"/>
<mx:TileList x="520" dataProvider="{this.imageArrayCollection}" itemRenderer="TileListRenderer" />
</mx:Application>
second file TileListRenderer.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100" height="140">
<mx:Script>
<![CDATA[
import mx.utils.ObjectUtil;
override public function set data(value:Object):void
{
super.data = value;
}
]]>
</mx:Script>
<mx:VBox horizontalAlign="center">
<mx:Image id="thumbHolder" source="{new Bitmap(data.bitmapData)}" maxWidth="100" maxHeight="100" />
<mx:Label text="{data.width}x{data.height}" />
</mx:VBox>
</mx:Canvas>
Because it is easier to see it with working source (right mouse button to see the source):
blog.arnomanders.nl/upload/imageResize/imageResize.html

Resources