hallikpapa
asked on
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?
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 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);
}
ASKER
Got these two errors on that line:
expecting semicolon before leftbracket.
this as not a valid type.
expecting semicolon before leftbracket.
this as not a valid type.
ASKER
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...
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...
Try this one:
var serviceWindow:Class =
this[managePopUp](PopUpMan ager.creat ePopUp(thi s, this[managePopUp], true));
var serviceWindow:Class =
this[managePopUp](PopUpMan
ASKER
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 .
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
Hmm:
var serviceWindow:Sprite =
this[managePopUp](PopUpMan ager.creat ePopUp(thi s, this[managePopUp], true));
var serviceWindow:Sprite =
this[managePopUp](PopUpMan
ASKER
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.
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
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.
ASKER
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.
Access of possibly undefined property users through a reference with static type flash.display:Sprite.
This is doable but I forgot how. Try
var serviceWindow:Class =
this[getDefinitionByName(m anagePopUp )](PopUpMa nager.crea tePopUp(th is, this[getDefinitionByName(m anagePopUp )], true));
var serviceWindow:Class =
this[getDefinitionByName(m
ASKER
Cool. thanks for the effort. now.....
ReferenceError: Error #1065: Variable Test is not defined.
at global/flash.utils::getDef initionByN ame()
at com::users/_servicePopUp() [Z:\src\co m\users.mx ml:122]
at com::users/___users_Label7 _click()[Z :\src\com\ users.mxml :218]
ReferenceError: Error #1065: Variable Test is not defined.
at global/flash.utils::getDef
at com::users/_servicePopUp()
at com::users/___users_Label7
just for testing try this:
var zzzTest:Test = new Test;
var serviceWindow:Class =
this[getDefinitionByName(m anagePopUp )](PopUpMa nager.crea tePopUp(th is, this[getDefinitionByName(m anagePopUp )], true));
var zzzTest:Test = new Test;
var serviceWindow:Class =
this[getDefinitionByName(m
ASKER
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\co m\users.mx ml:123]
at com::users/___users_Label7 _click()[Z :\src\com\ users.mxml :219]
ReferenceError: Error #1069: Property [class Test] not found on com.users and there is no default value.
at com::users/_servicePopUp()
at com::users/___users_Label7
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);
}
Can u try put the Text.mxml in the same folder then
var managePopUp:String = popUpName.getItemAt(e.curr entTarget. repeaterIn dex).servi ceSymbol;
var zzzTest:Test = new Test;
var serviceWindow:Class =
this[getDefinitionByName(m anagePopUp )](PopUpMa nager.crea tePopUp(th is,
this[getDefinitionByName(m anagePopUp )], true));
var managePopUp:String = popUpName.getItemAt(e.curr
var zzzTest:Test = new Test;
var serviceWindow:Class =
this[getDefinitionByName(m
this[getDefinitionByName(m
ASKER
I even tried just labeling it Test on top of dynamically grabbing it.
ReferenceError: Error #1065: Variable Test is not defined.
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));
OK I got it. Here are 2 samples files
Sample 1 the test component. Save it as TestComp
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>
File 2
Main.mxml
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>
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.
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.
ASKER
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...
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));
Is the mxml component in the same folder? You may need to import it.
ASKER
yeah it's in the same folder ,and I imported it.....How odd
Is this at the top of the script block?
private var tt:Test;
Also did you clean the project.
private var tt:Test;
Also did you clean the project.
ASKER
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.
I just cleaned the project , and it's still giving me that error.
There is no other reference to it? Can you post the full code?
ASKER
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>
Put Text.mxml in the same folder and change the import to:
import Test;
And see.
import Test;
And see.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Got an error "Definition Test could not be found"
Maddening isn't it.
Maddening isn't it.
ASKER
aha! that className:String = 'com.Test' did it
Thank you so much! This was a doozy
Thank you so much! This was a doozy
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
Did you try:
var ClassName:String = 'com.TestComp';
and leaving the Import as
import com.TestComp
Awsome!
var serviceWindow:this[manageP
this[managePopUp](PopUpMan