Jump to Navigation

How to reference Flex components created at runtime

We have been busy on a project for a client who wanted us to use flex . We knew nothing of flex so its been a bit of a learning curve.

During the last few week I learnt a lot and will over time post some of my learning as blog postings. I just had to post this solution to a problem we had in the hopes it helps others. It took a good couple of hours to work this out. If there is an easier way let me know, as I said I have just started with flex.

Flex components created dynamically at runtime

The app calls for a form to be created dynamically at runtime. The number,type and content of the form elements is also only know at run time. So you create your components with Actionscript and then add them to the parent container. In the code below I have left out iterating over the data and determining the type of component to create.

var textInput:TextInput = new TextInput();
textInput.id=item.modelns::name.text();
parent.addChild(textInput);

So we don't know how many of these there are, as it is dependent on the data returned form the web service. One thing we do have is the components id. In components designed using mxml you can refer to components by their id. E.G.

<mx:TextInput id="txtUsername" />

can be refered to in code like "txtUsername.text"

This makes access easy. (Basically when the flex compiler compiles your mxml file it create variables for each component with the id as the variable name.) Because ours components are declared at runtime we don't have this easy access mechanism available to us. According to some solutions I read, if you had the string representation for the component name, it's id or variable name, as a string you could go

this["txtUsername"]

to reference the component. But this only works if the component is known at compile time. Basically you are refering to the variable created by the compiler. BTW They refer to the Id as the component name when using this syntax. I suppose because it is the variable "name" created by the compiler but it can be confusing. At first I thought there needed to be another attribute on the component call "name".

Another solution offered was to create a variable for the component with component scope so you could refer to it later. Basically this is what the compiler does for components created with mxml.

Once again this won't work for component that you don't know will exist at compile time. In vain I looked for an API function such as getElementById. The closest I came was getChildByName but this seemed to refer to some objects that were not in the flex control

hierarchy .

The solution - use Dictionary Object

Eventually I decided to do the following:

  1. Create a Dictionary object with component scope,
  2. Every time a dynamic component was created place it in the dictionary with its "id" as the key,
  3. Retrieve the object form the dictionary when needed using the string representation of its "id"
private var componentBag:Dictionary; ....
private function createComponent():void{
var textInput:TextInput = new TextInput();
textInput.id=item.modelns::name.text();
parent.addChild(textInput);
componentBag[textInput.id]=textInput;
.....
later when I need to get the component reference var value:String
=componentBag[item.modelns::name.text()].text;
Open Source: 

Comments

I don't know if there exists another method, but your method definitely works. I went through the same ordeal trying to find out how to achieve this. Mind you, its a year later and this appears to me to be the only solution.

Please can you provide detailed steps and code regarding adding dynamic components based on XML.
I am new to flex.
Kindly help

I am having a component in one of the mxml file.

I am having a component in one of the mxml file.
mx:VideoDisplay id="video" height="100%" width="50%" autoPlay="false" autoRewind="true" styleName="videoStyle" source="{ presentationRecorder.media.videoRemoteUrl }"
I want to start this video by doing video.play() from some other actionscript file.
How can i access this VideoDisplay component from some other actionscript file using its id video.?
Please help me. I am new to flex.

Thanks a lot man.
I was looking for this for 2 hours now... almost going crazy :)

Hi!!!!

Thanks a lot... it was i needed!!! It was so helpfull for me..

Have a nice day...

Luis Alberto Diaz

Thanks. This didn't directly help me, but it got me started down the right path.

For the next person -
I'm creating dynamic forms based on XML. I need to be able to specify the ID of the newly created component. When you declare in an mxml file (say foo.mxml that has as it's root tag), the Flex compiler generates a class by the name CustomLabel that extends mx.Label and adds a public variable myLabel of type Label to it. This is why you are able to access it with this.myLabel. But when you assign a value to the id property of an object created at run time, no variable is added to the class and hence you cannot access it with this.id syntax.

A simple workaround is to declare an array, store the objects in that array and retrieve elements later as required. - Credit goes to
amarghosh.blogspot.com for this solution. It worked nicely for what I needed.

private var numComboDropDwns:Array = []; /* We need to store the objects in an array */
var c:ComboBox = new ComboBox ();
clabel=new Label();

clabel.text='Select ' + instFieldsArray[0];
if (numvalues != 0 )
{
c.dataProvider=newDropDown;
}else
{
c.enabled=false;
}
c.labelField='label';

c.width=250;
c.x=12;
c.y=0;
_h1.addChild(clabel);
_h1.addChild(c);
numComboDropDwns.push(c);

REFERENCE - http://stackoverflow.com/questions/2080518/how-to-reference-flex-elements-added-during-runtime

I hope this might help someone!

It helped me... thank you.

Thank you very much, this solved my problem with dynamic form fields.

Really... really thanks. this help me a lot



by Dr. Radut.