• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1204
  • Last Modified:

Dynamically call components

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
hallikpapa
Asked:
hallikpapa
  • 16
  • 14
1 Solution
 
Jones911Commented:
try this:


var serviceWindow:this[managePopUp] =
                this[managePopUp](PopUpManager.createPopUp(this, this[managePopUp], true));
0
 
hallikpapaAuthor Commented:
Got these two errors on that line:

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



0
 
hallikpapaAuthor Commented:
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
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

 
Jones911Commented:
Try this one:

var serviceWindow:Class =
                this[managePopUp](PopUpManager.createPopUp(this, this[managePopUp], true));
0
 
hallikpapaAuthor Commented:
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
 
Jones911Commented:
Hmm:

var serviceWindow:Sprite =
this[managePopUp](PopUpManager.createPopUp(this, this[managePopUp], true));
0
 
hallikpapaAuthor Commented:
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
 
hallikpapaAuthor Commented:
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
 
Jones911Commented:
This is doable but I forgot how. Try

var serviceWindow:Class =
this[getDefinitionByName(managePopUp)](PopUpManager.createPopUp(this, this[getDefinitionByName(managePopUp)], true));
0
 
hallikpapaAuthor Commented:
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
 
Jones911Commented:
just for testing try this:

var zzzTest:Test = new Test;
var serviceWindow:Class =
this[getDefinitionByName(managePopUp)](PopUpManager.createPopUp(this, this[getDefinitionByName(managePopUp)], true));
0
 
hallikpapaAuthor Commented:
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
 
Jones911Commented:
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
 
hallikpapaAuthor Commented:
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
 
Jones911Commented:
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
 
Jones911Commented:
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
 
Jones911Commented:
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
 
hallikpapaAuthor Commented:
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
 
Jones911Commented:
Is the mxml component in the same folder?  You may need to import it.
0
 
hallikpapaAuthor Commented:
yeah it's in the same folder ,and I imported it.....How odd
0
 
Jones911Commented:
Is this at the top of the script block?

private var tt:Test;

Also did you clean the project.
0
 
hallikpapaAuthor Commented:
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
 
Jones911Commented:
There is no other reference to it?  Can you post the full code?
0
 
hallikpapaAuthor Commented:
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
 
Jones911Commented:
Put Text.mxml in the same folder and change the import to:

import Test;

And see.
0
 
Jones911Commented:
Or

var ClassName:String = 'com.Test';
0
 
hallikpapaAuthor Commented:
Got an error "Definition Test could not be found"

Maddening isn't it.
0
 
hallikpapaAuthor Commented:
aha! that className:String = 'com.Test' did it

Thank you so much! This was a doozy
0
 
Jones911Commented:
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
 
Jones911Commented:
Awsome!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 16
  • 14
Tackle projects and never again get stuck behind a technical roadblock.
Join Now