Unload module event handling in flex - apache-flex

I am developing an AIR app. In the main app I have a module loader 'mainModuleLoader'. I am creating modules as separate mxml files using the <mx:Module> tag. And I am loading such a module in mainModuleLoader dynamically using actionscript. Everything works fine.
For the module which I am creating as mxml files, I would like to know how to add an unload event handler. So that, whenever I call mainModuleLoader.unload(), the unload event hander is triggered from inside the module.mxml. I have tried the following without any success.
<mx:Module creatingComplete="init()" unload="unloadHandler()"/>
<mx:Module creatingComplete="init()" remove="unloadHandler()"/>
The problem with the second statement above is that it triggers the unloadHandler even if some child is removed inside the module. I have also tried to add the following in the action script.
private function init()
{
this.addEventListener(ModuleEvent.UNLOAD, unloadHandler);
}
But, it doesn't trigger on unloading the module. Kindly let me know if I am going wrong somewhere or if there is any other method to attach the event handlers.
Thanks!!

You are part-way there with the remove; just check that event.target is the module before doing your work. It'll ignore the other ones then.

I think you have to handle the unload event of your mainModuleLoader:
<mx:ModuleLoader id="mainModuleLoader" unload="unloadHandler()"/>

Related

parsley and swfloader: famous domain propagation

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 to add Mate Listeners using Action Script

in one of my forms, I have used the following code for adding Mate Listeners
<mate:Listener type="{DBEvent.Update_Result}" receive="{onUpdateResults(event)}"/>
I am displaying this form as a popup. What happening is, for the first time, onUpdateResults method executed only once as expected. Then i close the popup and reopened it. This time onUpdateResults method called twice, then next 4time and so on...
After so much of googling, i found that Mate Listeners are still active, even though we remove/close the popup. I tried weak references, close the popup using PopupManager.RemovePopup and so on. Nothing worked.
Then i thought of registering and unregistering the mate listeners manually using action script. So, i have tried the following code
var _listener:Listener= new Listener();
_listener.addEventListener(DBEvent.Update_Result,onUpdateResults);
to unregister...
_listener.removeEventListener(DBEvent.Update_Result,onUpdateResults);
But this is also not working.
Please somebody help me fix this issue.
Try this.
Create runtime popup windows in main application:
PopUpManager.createPopUp(this, MyPopUp, true);
MyPopUp - mx:TitleWindow from MyPopUp.mxml
Add any listeners in OnInit in MyPopUp.mxml:
_listener.addEventListener(DBEvent.Update_Result, onUpdateResults);
Close popup when you click any button (button's click event or any):
PopUpManager.removePopUp(this);

FLEX: swfloader component not firing complete event

enter code hereBeen really frustrating just trying to load a swf from a swfloader in Flex and then accessing it's content. I'm sure once I figure out how to do it once then it'll be fine, but I've gone thorugh a bunch of tutorials and somethings not right. Here's my flex code:
and the as code:
public function initHeaderSwf():void
{
trace("INITIATIED");
//trace(headerSwf.content['weekNo'].text = "TWRTWERWEWE");
headerSwf.addEventListener(Event.COMPLETE, onHeaderLoaded);
}
private function onHeaderLoaded(evt:Event):void
{
trace("LOAD YOU JERK! = " + headerSwf.content['weekNo'].text);
}
Here's the problem:
The swf loads, there is no problem there. I see it in my compiled swf. but the complete event doesn't fire. CreationComplete will fire, and then I try, after that, to make a event listener for loading the actual swf, that doesn't fire. I've tried it a variety of different ways with no luck.
All I am trying to do is change a text field in the loaded swf. I imagine this might be a problem with the sequence of things loading or something like that, but not sure.
When are you adding the event listener? Is it possible you are adding the listener after the event has already fired?

Which event in the app's startup sequence is appropriate to trigger loading a config file in AIR/Flex?

I am working on a small AIR desktop application and I have some configuration infos that I want to store in a little file that's loaded at some point when the application starts and will be used to set public properties on the root application object. This should work just as if I had public variables declared in an <mx:Script> block at the beginning of my main MXML file.
I seem to have the choice of three events that could be used to initiate loading the configuration file:
invoke
initialize
creationComplete
Did I overlook some more? Which one is appropriate and why? Does it matter at all?
Example issues that come to my mind are:
are all components already accessible or will I get NULL references?
will some of my settings be overwritten in a phase that's coming after the event?
There's probably more.
If your handler needs to access UI components directly, you should wait for creationComplete; otherwise you'll get NULL references.
If you simply want to set properties on the root Application object, initialize seems the best place to do this. If you wait until creationComplete, and if the properties that you set are bound to your controls, then you might get a run-time resize or flicker as those components are updated.

Error #2099: The loading object is not sufficiently loaded to provide this information

I have a Flash app made up of AS3 components that I am trying to run in Flex.
In Flash, after the main component is added to the stage, the loader object (loaderInfo.loader) is null which is fine and I handle that.
In Flex, on the applicationComplete event I add the the main component to the stage and the loader object's getter throws an exception - Error #2099: The loading object is not sufficiently loaded to provide this information.
Also, the INIT event, which is dispatched when the properties and methods of a loaded SWF file are accessible, is not firing which is probably part of the problem. But I can't figure out why it is not being dispatched.
Any ideas why the same code has two different results?
Mmm, that seems like a frustrating problem. When you say "main component", I presume you mean the document class in Flash?
I'm not sufficiently knowledgeable about flex to comment on the problem you described, but I can suggest that you try using ADDED_TO_STAGE instead of INIT as your event...
public class MainFlashClass extends Sprite {
public function MainFlashClass() {
addEventListener(Event.ADDED_TO_STAGE, onInit);
}
public function onInit(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, onInit);
// do your initialisation code here
}
}
This might work for both scenarios. I've found ADDED_TO_STAGE to be more helpful because it always gets fired, whether the class is already loaded when the swf is executed (like the document class), or if it's being loaded with a Loader.
I'm not sure if this is what's going on with INIT event, but I do know that in flash player 9, which I'm assuming is the version of your SWF? There's a bug with referencing the loader through its own evt target. Basically if you are loading something and you try and access properties of the loader though evt.target.loaderInfo.loader it never can find itself and throws the error you described in your question. I believe it's a known bug for flash player 9 that was fixed with the release of CS4 and flash player 10.
Here's a link to a thread describing some of the problem, hopefully it helps
http://www.actionscript.org/forums/showthread.php3?t=137599
You definitely need to post code so we an see better.
With that said, after addChild are you attempting to grab the loaderInfo for the "main component" or for your mx:Application?
Pseudo
//onApplicationComplete event handler
var myswf:SWFLoader = new SWFLoader();
myswf.load(...);
addChild(nmyswf);
trace(myswf.loaderInfo.loader);
//end onApplicationComplete
Is that what you're doing? If so, you need to add an event listener to your "main component" (assuming an externally loaded swf) to find out when Event.COMPLETE happens.
var myswf:SWFLoader = new SWFLoader();
myswf.addEventListener(Event.COMPLETE, onMySWFComplete);
//..rest of code
Hope that helps. If not, post code.

Resources