?
Solved

Dynamically call components

Posted on 2009-02-13
30
Medium Priority
?
1,196 Views
Last Modified: 2013-11-11
I have a component called ServiceManage.mxml. It works great with the method listed. when I replace the word managePopUp with ServiceManage.

What I would like to do is dynamically call these pop up components as they are created. In the following example, managePopUp is being populated with the word "Test", and there is a Test.mxml, which is a duplicate of ServiceManage.mxml

On the var serviceWindow:managePopUp...... (I also tried it with a defined type of String instead of Class, but it gave me an error like it wanted it to be a class)

I get the following error:
Type was not found or was not a compile-time constant: managePopUp.      

Test.mxml is in the com folder. So the managePopUp var contains "com.Test", as a string though. Trying to make flex find that component...

Second question:
I am clicking on labels in the repeater index. Is it possible to make it so labels are only underlined and bolded if it finds a component that matches the name in managePopUp?


private function _servicePopUp(e:Event):void {
	//Pop up window for individual services. Component name must match service symbol name in DB
	var popUpName:ArrayCollection = new ArrayCollection( ArrayUtil.toArray( selectedUser.services ) );
	var managePopUp:Class = popUpName.getItemAt(e.currentTarget.repeaterIndex).serviceSymbol;
    var serviceWindow:managePopUp = 
        	managePopUp(PopUpManager.createPopUp(this, managePopUp, true));
 
    serviceWindow.bindGate = bindGate;
    var user:UserVO = UserVO(selectedUser);
    serviceWindow.user = user;
    PopUpManager.centerPopUp(serviceWindow); 
}

Open in new window

0
Comment
Question by:hallikpapa
  • 16
  • 14
30 Comments
 
LVL 19

Expert Comment

by:Jones911
ID: 23637899
try this:


var serviceWindow:this[managePopUp] =
                this[managePopUp](PopUpManager.createPopUp(this, this[managePopUp], true));
0
 

Author Comment

by:hallikpapa
ID: 23637942
Got these two errors on that line:

expecting semicolon before leftbracket.      
 this as not a valid type.      



0
 

Author Comment

by:hallikpapa
ID: 23638104
managePopUp = "com.Test" --> (when created dynamically)
serviceWindow = com.Test (@43830a1) -->(when Test replaces managePopUp

That's the difference, so I need to do something to the value of managePopUp to convert it from a string to whatever flex needs it to be...
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 19

Expert Comment

by:Jones911
ID: 23638117
Try this one:

var serviceWindow:Class =
                this[managePopUp](PopUpManager.createPopUp(this, this[managePopUp], true));
0
 

Author Comment

by:hallikpapa
ID: 23638184
I feel like a little progress is being made.

This is the current error:
 Implicit coercion of a value of type Class to an unrelated type mx.core:IFlexDisplayObject.

I changed the word Class to IFlexDisplayObject, and it bombed out on the serviceWindow.bindgate line & the serviceWindow.user line with an error:

Access of possibly undefined property bindGate through a reference with static type mx.core:IFlexDisplayObject.
Access of possibly undefined property user through a reference with static type mx.core:IFlexDisplayObject.



0
 
LVL 19

Expert Comment

by:Jones911
ID: 23638208
Hmm:

var serviceWindow:Sprite =
this[managePopUp](PopUpManager.createPopUp(this, this[managePopUp], true));
0
 

Author Comment

by:hallikpapa
ID: 23638232
Got this error again:

Access of possibly undefined property bindGate through a reference with static type mx.core:IFlexDisplayObject.
Access of possibly undefined property user through a reference with static type mx.core:IFlexDisplayObject.

I must add that " Implicit coercion of a value of type Class to an unrelated type mx.core:IFlexDisplayObject." happened on the centerPopUp line...

I commented that out, and it compiled ok, but died when it got to the var serviceWindow:Class line with this error

ReferenceError: Error #1069: Property com.Test not found on com.users and there is no default value.


And there is most defintely a Test.mxml in the com folder.

0
 

Author Comment

by:hallikpapa
ID: 23638245
Oops sorry, change the first two errors on the last comment to

Access of possibly undefined property users through a reference with static type flash.display:Sprite.
0
 
LVL 19

Expert Comment

by:Jones911
ID: 23638274
This is doable but I forgot how. Try

var serviceWindow:Class =
this[getDefinitionByName(managePopUp)](PopUpManager.createPopUp(this, this[getDefinitionByName(managePopUp)], true));
0
 

Author Comment

by:hallikpapa
ID: 23638294
Cool. thanks for the effort. now.....

ReferenceError: Error #1065: Variable Test is not defined.
      at global/flash.utils::getDefinitionByName()
      at com::users/_servicePopUp()[Z:\src\com\users.mxml:122]
      at com::users/___users_Label7_click()[Z:\src\com\users.mxml:218]
0
 
LVL 19

Expert Comment

by:Jones911
ID: 23638340
just for testing try this:

var zzzTest:Test = new Test;
var serviceWindow:Class =
this[getDefinitionByName(managePopUp)](PopUpManager.createPopUp(this, this[getDefinitionByName(managePopUp)], true));
0
 

Author Comment

by:hallikpapa
ID: 23638430
This is what my function looks like now, with this error:

ReferenceError: Error #1069: Property [class Test] not found on com.users and there is no default value.
      at com::users/_servicePopUp()[Z:\src\com\users.mxml:123]
      at com::users/___users_Label7_click()[Z:\src\com\users.mxml:219]


private function _servicePopUp(e:Event):void {
	//Pop up window for individual services. Component name must match service symbol name in DB
	var popUpName:ArrayCollection = new ArrayCollection( ArrayUtil.toArray( selectedUser.services ) );
	var managePopUp:String = "com." + popUpName.getItemAt(e.currentTarget.repeaterIndex).serviceSymbol;
 
    var zzzTest:Test = new Test;
	var serviceWindow:Class = 
		this[getDefinitionByName(managePopUp)](PopUpManager.createPopUp(this, 
			this[getDefinitionByName(managePopUp)], true));
    		
    serviceWindow.bindGate = bindGate;
    var user:UserVO = UserVO(selectedUser);
    serviceWindow.user = user;
    //PopUpManager.centerPopUp(serviceWindow); 
}

Open in new window

0
 
LVL 19

Expert Comment

by:Jones911
ID: 23638445
Can u try put the Text.mxml in the same folder then

var managePopUp:String = popUpName.getItemAt(e.currentTarget.repeaterIndex).serviceSymbol;
 
    var zzzTest:Test = new Test;
        var serviceWindow:Class =
                this[getDefinitionByName(managePopUp)](PopUpManager.createPopUp(this,
                        this[getDefinitionByName(managePopUp)], true));
0
 

Author Comment

by:hallikpapa
ID: 23638630
I even tried just labeling it Test on top of dynamically grabbing it.

ReferenceError: Error #1065: Variable Test is not defined.
managePopUp = "Test";
    			var zzzTest:Test = new Test;
        		var serviceWindow:Class = 
                	this[getDefinitionByName(managePopUp)](PopUpManager.createPopUp(this, 
                        this[getDefinitionByName(managePopUp)], true));

Open in new window

0
 
LVL 19

Expert Comment

by:Jones911
ID: 23638762
OK I got it.  Here are 2 samples files

Sample 1 the test component.  Save it as TestComp
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" width="236" height="170">
	<mx:CheckBox x="187" y="96" label="Checkbox"/>
</mx:TitleWindow>

Open in new window

0
 
LVL 19

Expert Comment

by:Jones911
ID: 23638763
File 2

Main.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"  xmlns:ns1="*" creationComplete="init()">
	<mx:Script>
		<![CDATA[
			import mx.managers.PopUpManager;
			private var t:TestComp;
			
			private function init():void{
				var ClassName:String = 'TestComp';
				var dynObject:Class = getDefinitionByName(ClassName) as Class;
				var popUp:Object = dynObject(PopUpManager.createPopUp(this, dynObject, true));
			}
		]]>
	</mx:Script>
	
</mx:Application>

Open in new window

0
 
LVL 19

Expert Comment

by:Jones911
ID: 23638768
I remember why it didn't work they way you expect its because you need to declaire one instance of it or it never know show to reference that same component hence this line:

private var t:TestComp;

Its doing nothing but without it the example fails.  So for your example you would have to create one instance of every popup type at the top on the function.
0
 

Author Comment

by:hallikpapa
ID: 23638857
Your example works perfectly, but somehow I cannot apply the same logic in my app? I still get that "Variable Test is not defined"

The Test.mxml is in the same folder as the component that calls this. I will continue to play around...




private var tt:Test;
...
...
...
 
var ClassName:String = 'Test';
                var dynObject:Class = getDefinitionByName(ClassName) as Class;
                var popUp:Object = dynObject(PopUpManager.createPopUp(this, dynObject, true));

Open in new window

0
 
LVL 19

Expert Comment

by:Jones911
ID: 23638861
Is the mxml component in the same folder?  You may need to import it.
0
 

Author Comment

by:hallikpapa
ID: 23638875
yeah it's in the same folder ,and I imported it.....How odd
0
 
LVL 19

Expert Comment

by:Jones911
ID: 23638893
Is this at the top of the script block?

private var tt:Test;

Also did you clean the project.
0
 

Author Comment

by:hallikpapa
ID: 23638913
Yeah private var tt:Test is with the rest of my class vars right after the imports at the top.

I just cleaned the project , and it's still giving me that error.
0
 
LVL 19

Expert Comment

by:Jones911
ID: 23638926
There is no other reference to it?  Can you post the full code?
0
 

Author Comment

by:hallikpapa
ID: 23638942
here is the whole users.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" creationComplete="init()">
	<mx:Script>
		<![CDATA[
			import mx.utils.ObjectProxy;
			import mx.events.DataGridEvent;
			import mx.controls.Button;
			import mx.rpc.remoting.mxml.RemoteObject;
			import mx.rpc.events.ResultEvent;
            		import mx.rpc.events.FaultEvent;
			import mx.managers.PopUpManager;
			import mx.controls.Alert;
			import mx.utils.ArrayUtil;
			import mx.collections.ArrayCollection;
			import com.Test;
			
			[Bindable] private var selectedUser:UserVO;			
			
			[ArrayElementType("com.vo.UserVO")]			
			[Bindable] public var userList:ArrayCollection;
			
			
			[Bindable] public var oneUser:Object;
			[Bindable] public var gateway:String;
			protected var bindGate:Object;
			public var params:Object = {};
			private var tt:Test;
			
			
			[Bindable] public var conn:RemoteObject;
			
			private function init():void
			{
				activeUsers.label = "All Users";
			}
            
            		public function remoteConnect(gateway:String):void
			{
				conn = new RemoteObject;
				conn.source = "UserAcctService";
				conn.destination = "amfphp";
				conn.endpoint = gateway;
				conn.getUsers.showBusyCursor = true;
                conn.getUsers.addEventListener("result", getUsersResultHandler);
                conn.addEventListener("fault", _faultHandler);
                bindGate = conn;
                conn.getUsers();
            }
 
            public function getUsersResultHandler(event:ResultEvent):void {
                userList= new ArrayCollection(event.result as Array);
            }
            
            private function _getOneResult(event:ResultEvent):void {              
                selectedUser.services = event.result.services as Array;
            }
 
            private function _faultHandler (event:FaultEvent):void {
                Alert.show(event.fault.faultString, 'Error');
            }
 
			private function updateUser():void			
			{				
				var update:UserVO 		= new UserVO();
	 				update.id 			= selectedUser.id;
					update.firstName 	= txt_fname.text;
					update.lastName 	= txt_lname.text;
					update.email		= txt_email.text; 
					update.userActive 	= userActive.selected;
					update.userAdmin 	= userAdmin.selected;
				
					for(var i:String in selectedUser.services)
					{
						var services:ServiceVO 	= new ServiceVO();
						services.serviceID		= selectedUser.services[i].serviceID;
						services.serviceName	= selectedUser.services[i].serviceName;
						services.mappedName 	= userMappedName[i].text;
						services.mappedActive 	= serviceMappedActive[i].selected;
						update.services[i] 		= services;
					}
					 
				conn.saveUser.addEventListener("result", _getOneResult);
				conn.saveUser.addEventListener("fault", _faultHandler);
				conn.saveUser.showBusyCursor = true;
	            conn.saveUser(update);
			}
	
 
			private function _selectHandler( event:Event ):void
			{
				selectedUser = event.target.selectedItem as UserVO;
				if ( selectedUser != null )
				{
					conn.getOne.addEventListener("result", _getOneResult);
					conn.getOne.addEventListener("fault", _faultHandler);
                	conn.getOne(selectedUser.id);
				}
			}
 
			private function _newUser():void {
                var userWindow:NewUser = 
                    	NewUser(PopUpManager.createPopUp(this, NewUser, true));
                PopUpManager.centerPopUp(userWindow); 
                userWindow.bindGate = bindGate;
            }
            
            private function _servicePopUp(e:Event):void {
            	//Pop up window for individual services. Component name must match service symbol name in DB
            	
            	var popUpName:ArrayCollection = new ArrayCollection( ArrayUtil.toArray( selectedUser.services ) );
            	var managePopUp:String = popUpName.getItemAt(e.currentTarget.repeaterIndex).serviceSymbol;
 				
 				var ClassName:String = 'Test';
                var dynObject:Class = getDefinitionByName(ClassName) as Class;
                var popUp:Object = dynObject(PopUpManager.createPopUp(this, dynObject, true));
                		
                popUp.bindGate = bindGate;
                var user:UserVO = UserVO(selectedUser);
                popUp.user = user;
                //PopUpManager.centerPopUp(serviceWindow); 
            }
            
            private function _resetPassword():void {
            	var resetWindow:ResetPassword = 
               		ResetPassword(PopUpManager.createPopUp(this, ResetPassword, true));
                PopUpManager.centerPopUp(resetWindow); 
                resetWindow.loginName = selectedUser.userName;  
                resetWindow.bindGate = bindGate;     
            }
            
            private function _activeUsersChange(toggle:Boolean):void {
            	if(activeUsers.selected == true)
            	{
            		activeUsers.label = "Active Users";
            	}
            	else
            	{
            		activeUsers.label = "All Users";
            	}
            	conn.toggleUsers.addEventListener("result", getUsersResultHandler);
				conn.toggleUsers.addEventListener("fault", _faultHandler);
            	conn.toggleUsers(toggle);
            }
		]]>
	</mx:Script>
		<mx:HDividedBox width="100%" height="100%" label="Users">			
			<mx:Panel title="User Details"
				width="75%"
				height="75%"
				layout="vertical" cornerRadius="10">
									
				<mx:Form width="100%" height="100%" cornerRadius="10">
					<mx:FormHeading label=""/>
					
					<mx:FormItem label="User Name:" width="100%" direction="horizontal">
						<mx:Label text="{selectedUser.userName}"/>
					</mx:FormItem>
										
					<mx:FormItem label="" direction="horizontal">
						<mx:Label text="User Active:"/>
						<mx:CheckBox id="userActive" data="{selectedUser.userActive}"/>
						<mx:Label text="User Admin:"/>
						<mx:CheckBox id="userAdmin" data="{selectedUser.userAdmin}"/>
					</mx:FormItem>
						
					<mx:FormItem label="First Name:" width="75%" required="true">
						<mx:TextInput id="txt_fname"
							text="{ selectedUser.firstName }" width="75%"/>
					</mx:FormItem>
						
					<mx:FormItem label="Last Name:" width="75%" required="true">
						<mx:TextInput id="txt_lname"
							text="{ selectedUser.lastName }" width="75%"/>
					</mx:FormItem>
					
					<mx:FormItem label="Rank:" width="75%" required="true">
						<mx:TextInput id="txt_rank"
							text="{ selectedUser.userRank }" width="75%"/>
					</mx:FormItem>
						
					<mx:FormItem label="Email:" width="75%" required="true">
						<mx:TextInput id="txt_email"
							text="{ selectedUser.email }" width="75%"/>
					</mx:FormItem>
						
					<mx:FormItem label="Created At:" width="75%" required="false">
						<mx:Text id="txt_createdAt"
								text="{ selectedUser.createdAt }" width="75%"/>
					</mx:FormItem>
						
					<mx:FormItem label="Updated At:" width="75%" required="false">
						<mx:Text id="txt_updatedAt"
								text="{ selectedUser.updatedAt }" width="75%"/>
					</mx:FormItem>
					</mx:Form>
					<mx:Form>
					<mx:HRule width="391"/>
					
					<mx:FormItem direction="horizontal">
						<mx:Label width="150" text="Service Name" fontWeight="bold"/>
						<mx:Label width="150" text="Provider Specific Login" fontWeight="bold"/>
						<mx:Label width="175" text="Active" fontWeight="bold"/>
					</mx:FormItem>
					
					<mx:Repeater id="sp" dataProvider="{selectedUser.services}">					  
						<mx:FormItem direction="horizontal">
							<mx:Label width="150" click="_servicePopUp(event)" text="{sp.currentItem.serviceName}:" 
								textDecoration="underline" useHandCursor="true"/>							
							<mx:TextInput width="150" id="userMappedName" text="{ sp.currentItem.mappedName }"/>
							<mx:CheckBox width="175" id="serviceMappedActive" selected="{sp.currentItem.mappedActive}"/>
						</mx:FormItem>
		        	</mx:Repeater>
						
					<mx:FormItem label="" direction="horizontal" width="100%">
						<mx:Button label="Save"	click="updateUser()"/>
					</mx:FormItem>		
				</mx:Form>				
			</mx:Panel>
			
			<mx:Panel title="Users"
				width="75%"
				height="75%"
				layout="vertical" alpha="1.0">			
				<mx:DataGrid id="dg_users"
					width="100%"
					height="100%"
					change="_selectHandler( event )"
					dataProvider="{ userList }">			
					<mx:columns>
						<mx:DataGridColumn headerText="ID" dataField="id" width="50"/>
						<mx:DataGridColumn headerText="User Name" dataField="userName"/>
						<mx:DataGridColumn headerText="Last Name" dataField="lastName"/>
						<mx:DataGridColumn headerText="First Name" dataField="firstName"/>						
						<mx:DataGridColumn headerText="Email" dataField="email"/>
					</mx:columns>
				</mx:DataGrid>
				<mx:FormItem label="" direction="horizontal" width="100%">
					<mx:Button label="Refresh" click="conn.getUsers()"/>
					<mx:Button label="New User"	click="_newUser()"/>
					<mx:Button label="Reset Password" click="_resetPassword()"/>
					<mx:Button id="activeUsers"
            			label="{activeUsers.label}"
            			toggle="true"
            			click="_activeUsersChange(activeUsers.selected)"/>
				</mx:FormItem>
			</mx:Panel>
		</mx:HDividedBox>
	
</mx:VBox>

Open in new window

0
 
LVL 19

Expert Comment

by:Jones911
ID: 23638972
Put Text.mxml in the same folder and change the import to:

import Test;

And see.
0
 
LVL 19

Accepted Solution

by:
Jones911 earned 2000 total points
ID: 23638984
Or

var ClassName:String = 'com.Test';
0
 

Author Comment

by:hallikpapa
ID: 23638988
Got an error "Definition Test could not be found"

Maddening isn't it.
0
 

Author Comment

by:hallikpapa
ID: 23638991
aha! that className:String = 'com.Test' did it

Thank you so much! This was a doozy
0
 
LVL 19

Expert Comment

by:Jones911
ID: 23638993
Try change test to TestComp or something different incase there are some duplicates somewhere.

Did you try:

var ClassName:String = 'com.TestComp';

and leaving the Import as

import com.TestComp
0
 
LVL 19

Expert Comment

by:Jones911
ID: 23638996
Awsome!
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I come across a lot of question about how to access things in the document class from a movieclip, or accessing something from a movieclip in the document class. It took me a while to figure this out but once I did it makes life so much easier. …
The last time I worked with Flash and Socket connections was in AS1. A recent project required flash connecting to a Socket, and sending receiving information - we figured it would be easy enough - we all know about the socket policy documents and c…
The goal of the tutorial is to teach the user how to how to record live broadcast.
This Micro Tutorial will teach to how to utilize bit rate in Adobe Flash Media Live Encoder.
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question