Hi
In our flex application we have tabs at the main level and under it we have subview.
e.g
Home / Tasks / Admin etc...
In one condition we have to click on a button and open a new tab, on this tab we have to add an existing mxml component and show it in the tab.
We are using parsley as the framework.
Inside the mxml component test.mxml (that is shown in the tab) i am configuring it with parsley using the tag
Now when i add the instance of this test.mxml i am getting an exception
I am deriving this test.mxml instance using teh parsley context
as
context.getObject(id of component) as DisplayObject and adding it to the tabNavigator...
But i am getting exception when i try to grab an instance of a view using parsley context.
How do i get an instance of a view or component that is configure through parsley using the parslye context.
posting some code
in parsley context mxml file
in mediator class
public class TestMediator {
[Inject(id="testViewID")]
public var testView:TestView;
and then i add this view object to a container....
Also the problem is occuring becuase of the view injection..because i get a parsley excepiton on startup of the application stating that there is some problem in the context.
What exception are you getting? Without this information it's hard to help you out.
Anyways, here are some thoughts:
creating views through the container should not be a problem
note that MXML components can't take constructor arguments, so make sure you don't have any in your object definition
children of the tab navigator should be containers, not just display objects
Related
we've got two applications (not modules, two independent applications!): A and B. both are Parsley-managed and we'd like to embed B in A using SWFLoader (but, and i stress that, we don't want to "connect" these applications using Parsley, we just want to do normal Flash embedding) .
that's embed code:
<fx:Script>
<![CDATA[
[Bindable]
private var childDomain:ApplicationDomain =
new ApplicationDomain(ApplicationDomain.currentDomain);
]]>
</fx:Script>
<mx:SWFLoader width="100%" height="100%" source="B.swf"
complete="initNestedAppProps(SWFLoader(event.currentTarget).content);"
loaderContext="{new LoaderContext(false, childDomain, SecurityDomain.currentDomain)}"/>
and it works when i embed B in a dummy app without Parsley.
however, when i copy-paste that embed code in live application A, Parsley throws this famous error:
ReferenceError: Specified ApplicationDomain does not contain the class _B_mx_managers_SystemManager
even if the view that contains embedding code is not Parsley-configured (and doesn't have <Configure/> tag).
i can't post this on Parsley forums unfortunately and googling didn't help as it seems people don't do application embedding too often.
so the question is, why does this error happen (Parsley shouldn't care about stuff in embedded application, should it?) and how can tell Parsley to properly use my childDomain?
The problem is that Parsley is bubbling events up the display list so that a context can use them to inject properties etc.
Despite the fact your sub application is in a separate application domain, events can still bubble up from the swf loader's child to the parent and so on.
What is happening is that your sub application is bubbling events that are getting handled by your shells (or wrapper/loader applications) context, however when parsley then tries to reflect on this object it can't because the object doesn't exist in it's application domain.
The solution is to stop these events getting to your shell application's parsley context. You can do this a number of ways, for example you could just add listeners for the events and stop their propagation. However this would mean you would have to add listeners for all Parsley events, which could change in the future. A better solution is to create a new context in your SWFLoader’s parent that has an autowireFilter that returns ViewAutowireMode.NEVER for displayObjects passed to it.
This context will stop them bubbling any further and will stop parsley reflecting on them, and therefore stop the problem with them not being in the application domain.
See: org.spicefactory.parsley.core.view.impl.DefaultViewAutowireFilter
org.spicefactory.parsley.core.builder.impl.DefaultCompositeContextBuilder
http://opensource.powerflasher.com/jira/browse/PSL-587
Hope this helps.
the above answer is correct.
in our case i solved the problem by writing a flex module and using ModuleLoader instead of SWFLoader, which is nicely integrated with Parsley.
How can I use custom code (activity file not codeactivity neither activitydesginer ) as an Activity inside a Reshosted workflow designer?
I was doing the following for any activity, which I build for each ( codeactivity & activitydesginer) files, and wirte:
new ToolboxCategory("new Toolbox")
{
Tools=
{
new ToolboxItemWrapper(typeof(Flowchart)),
new ToolboxItemWrapper(typeof(SimpleWebDesigner.TEST)),
....etc
AnyHelp?
If you're talking about loading an Activity loaded from a loose xaml file, you can do this.
You have to use the the ActivityXamlServices class to Load(filename) the file at runtime. When you do this, you get the deserialized Activity instance. Of course, you must have any relevant assemblies (any assembly referenced by Activities defined in the xaml file) either loaded in the AppDomain or available for loading where the Fusion loader can find them.
Once you do this, you can create a ToolboxItemWrapper passing in activityInstance.GetType().
One thing, since the Activity xaml file is an Activity which holds other Activities, you will get the default Designer, which only shows a blank header. There is no easy way* to expand the child Activities defined in the xaml file in the designer when you drop them on the design surface.
*I believe you can construct a class that implements IActivityTemplateFactory which you can pass to the ToolboxItemWrapper which can pass the root Activity defined within your xaml file, so that when you drag/drop the item from the toolbox it will automatically add all child Activities defined in the xaml file. But I've never done this and am not sure if you can.
I would like to add custom right clicks to a number of spark list controls.
I have tried the following as an item renderer. (as per the flex 4 cook book).
Full Render code here http://pastebin.com/Kx8tJ1cY
When I right click on the Spark List I simply get the Adobe Default Context menu.
This is the same default behaviour I had before I added any code to this.
Could anyone tell me how to add right clicks to List Items in Flex 4.
Please and Thank you.
I found the problem/solution. You cant use context menus if there are Vboxes or Tab Navigators. Which is insane because it means I cant do relative layout properly or decent variable width design.
Quoted from: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/ui/ContextMenu.html
For example, if a DataGrid control is a child of a TabNavigator or VBox container, the DataGrid control cannot have its own context menu.
Christopher Huyler posted something similar (source code available here). From the article:
Start out by grabbing the Javascript code from Google's code repository.
Step 1 – Setup custom context menu code
Create a new Flex project in Flex Builder. Copy rightclick.js and swfobject.js into the html-template folder of your project. From here, I had to make several changes…
I modified the RightClick.init() function to accept an object and container value as input. This allows me to pass in the name of the application as the object instead of having it be called the same thing every time.
I included rightclick.js and swfobject.js in the header of index.template.html.
I added a new div to the body called “flashcontent”.
I added an onload handler to the body tag to initialize RightClick
I replaced AC_FL_RunContent(…) with new SWFObject(…) making sure to maintain all template variables.
After making these changes, I verified that no right-click context menu appears in my application.
Step 2 – Listen for the rightClick event
Next I added a few lines to the main mxml file of my application to listen for the ExternalInterface event that will be dispatched when I right-click my appliction.
private function handleCreationComplete():void
{
ExternalInterface.addCallback("rightClick", handleRightClick);
}
private function handleRightClick():void
{
Alert.show("Right Click Success!");
}
Step 3 – Dispatch an event to the correct object
Getting the event to the main application is easy, but we actually want the appropriate child object to be notified when the right-click event occurs. Since I am not using any double-click events in my application I decided I would treat every right-click event like a double-click event. Users without a two button mouse (aka Mac users) can simply double-click to get the same menu while users with a two button mouse just have to right-click. Here is how I make sure the event is dispatched to the appropriate object.
private function handleRightClick():void
{
var objects:Array = systemManager.getObjectsUnderPoint(
new Point(mouseX,mouseY));
if (objects.length>0)
{
var object:Object = objects[objects.length-1];
var relatedObject:InteractiveObject;
if (object is InteractiveObject)
relatedObject = object as InteractiveObject;
else if (object.parent && object.parent is InteractiveObject)
relatedObject = object.parent;
var event:MouseEvent = new MouseEvent(
MouseEvent.DOUBLE_CLICK,true,false,mouseX,mouseY,
relatedObject);
object.dispatchEvent(event);
}
}
I hope this helps!
How can I add an MXML component as a child of the main application using ActionScript. It's not possible to instatiate it, is it? Assuming that behind every mxml file stands an actionscrpt3 class, I tried to import it but id didn't show up.
You'll want to familiarize yourself with the flex component lifecycle: http://msimtiyaz.wordpress.com/flex/adobe-flex-component-instantiation-life-cycle/
It explains the actionscript code behind the mxml components, and it's important to be familiar with, because if you implement your components incorrectly, it can really slow down your application.
Anyway, I think you may be confused about what imports do. Import statements make the code available to use in your code, but it wouldn't create a component. You'd need to create a component the same way you create any object in actionscript, and then you'll need to add that component to the display list to make it show up.
The appropriate place to do this is in the createChildren() function:
override protected function createChildren():void {
super.createChildren();
var myText:Text = new Text();//create a new object
this.addChild(myText);//add it to the display list
}
I have a TitleWindow mxml class wich has several components, and listeners.
On its creationComplete and init state i add some listeners which listen for events on its gui.
This TitleWindow is only shown when the user click on a "button", i made TitleWindow a singleton with the following code:
public static function getInstance():MyWindow
{
if ( MyWindow.singleton )
{
return MyWindow.singleton;
}
else{
MyWindow.singleton = new MyWindow();
return MyWindow.singleton;
}
}
I needed a singleton because the user will call this window several times as much as he wants and i only need one.
The problem is the following on some special external events i need to "modify" some listeners (remove listeners and add new ones) on a button from MyWindow, before it was even shown once.
I still have MyWindow.getInstance() in memory when my application starts up.
However adding /removing listeners does not seem to have any effect if he actual rendering of the components did not happen, event when using the following code on app startup.
myWindow= MyWindow.getInstance();
myWindow.initialize();
Not suprisingly if i "show" ('render') the myWindow at least once then the events modifications on the myWindow instance works perfectly.
How can i fake the complete initialisation of this component without showing it on startup ?
Thanks !
Which sort of a container holds your button? If you are using a Multiple View Container you can try setting the creationPolicy to all. Single View Containers create all their children in one go and you shouldn't face this problem.
From Flex 3.0 docs I could retrieve this:
The default creation policy for all containers, except the Application container, is the policy of the parent container. The default policy for the Application container is auto.
This looks like the cause for all your troubles.
Update: I did not mention this earlier, since I thought this was to be expected :) Setting the creationPolicy to all makes your application load more slowly. So, read up on Ordered Creation -- this technique helps you to choose if the controls are displayed all in one go (which is the default behavior, after all of the controls have been created) or step-by-step, as and when they are created.