How can I remove all event listeners on all components at once, especially when it is not known what listeners are attached to each component?
You can override mx.core.FlexSprite, which UIComponent inherets from, and generate an array of listeners created. Doug Mc Cune put up source code here.
His blog says: removeAllEventListeners() – removes all event listeners of all types. This completely wipes out all event listeners for the component all at once.
Let us know if this does the job!
No!
You might be able to mock something up with hasEventListener and willTrigger. But, there doesn't appear to be an obvious way to remove the event listeners without actually knowing the method name.
What do you want to do this for?
There is an issue in Adobe JIRA for this task, please vote if you feel that it important for you
https://bugs.adobe.com/jira/browse/SDK-14127
Elad Elrom has a post on his implementation to store event listener references, and be able to remove them all at once:
http://elromdesign.com/blog/2010/07/16/easy-way-to-store-event-listeners-reference-prevent-memory-leaks/
Related
Do I need to remove event listeners on AsyncResponder events?
i.e.
public function DeleteItem():void
{
var asyncResponse:AsyncResponder = new AsyncResponder(DeleteItem_Result, DeleteItem_Fail);
_myService.DeleteWorkout("test", asyncResponse);
}
private function DeleteItem_Result(event:Event):void
{
//If I do need to remove them, how do i remove the async responder event listeners?
}
If I do need to remove them, how do I do it?
Do I need to remove event listeners on AsyncResponder events?
No, you do not. If you are creating the AsyncResponder and using ot over and over again, then by all means leave the listeners in there.
However, in some cases, if you won't be reusing the component over and over; I would recommend you do remove the event listeners, as that will remove a dependency pointing at the asyncResponder which may allow it to be released for garbage collection as appropriate.
In the Adobe Flex Framework it is pretty common to add and remove listeners "as needed." We use the approach in the Flextras Calendar, for example, when dealing with effects. Before starting the effect we add some event listeners for 'effect end'. Those listeners are removed in that effect end method.
Update:
To remove an event listener you would use code similar to this:
asyncResponder.removeEventListener('result' ,UpdatePics_result);
asyncResponder.removeEventListener('fault' ,UpdatePics_fault);
I'm removing an UIComponent but parts of it last being visible.
It redraws only when I move mouse around or something. I tried to do validateNow() on its parent, tried to do setTimeout(validateNow, 100) but it doesn't help. When I call it by setTimeout it seems these artifacts shown more rarely but it doesn't solve a problem in all cases. Please guide me someone to read about validateNow(), how it works and how to make these things correctly.
The code is below:
protected var bubble: SpeechBubble;
// creation
bubble = new SpeechBubble();
map.addChild(bubble);
//...
// removing
bubble.visible = false;
map.removeChild(bubble);
map.validateNow();
setTimeout(map.validateNow, 100);
map is Google Map for Flex.
The reason this is happening is because you're messing with the Google Maps drawing logic. You should look at the developer guide provided by google. It mentions in the controls section that to create a custom control, you need to extend ControlBase.
You may need to trigger invalidation before calling validateNow(). The call to validate now causes the code to check if any of the invalidation flags are set (properties, display list, or size) then for each calls the appropriate method to correct the invalidation (commitProperties, updateDisplayList, measure) in your case it sounds like it's just not doing the clear call to the graphics or redrawing appropriately so you may need to call
bubble.invalidateDisplayList();
bubble.validateNow();
Also hope one of these solutions works out for you, generally speaking forcing validation at a given time is not usually a good idea as the framework components should trigger the appropriate invalidation and subsequent validation in it's life cycle, but I can't say I haven't done this myself :).
Shaun
You may use includeInLayout property
bubble.visible = false;
bubble.includeInLayout = false;
Example demonstrates this property
The Beauty of includeInLayout
hopes that helps
Below is the overriden on complete function for a preloader in Flex.
private function initComplete(e:Event):void
{
//dispatchEvent(new Event(Event.COMPLETE));
cp.status.text="Configuring... Please Wait";
}
What I want to do is when the app has finsihed loading I want to change the preloaders text to "configuring".
Then I want to go and do a bunch of setup stuff in my code.
Once I've done all the setup I wanted how can I get the Preloader to dispatch its Event.complete from else where in my code?
I tried Application.application.preloader but it comes up null.
So I guess my question really is how to access a preloader from anywhere in my application.
Would a better approach be to have all setup classes as members of my preloader class?
One thing that might help is a Model-View-Controller pattern. Are you using a framework for your application like Mate, Swiz, or Cairngorm?
If you were using Mate, for example, you could do something like this:
Create an AppStateManager class with a property (e.g. applicationState)
Create an EventMap with an EventHandler for the FlexEvent.INITIALIZE event. In this handler, set the AppStateManager.applicationState to something like "CONFIGURING"
Your EventMap has an injector that injects the applicationState property into a view. The injector listens for changes to this property and updates the view. In this case it might just be injected into your main view.
In the main view, you have a public bindable property also called applicationState that gets injected by Mate.
In the setter for this property, you can have an if/then or a switch that does different tasks depending on the state. For example, if applicationState == "COMPLETE", then this.preloader.dispatchEvent(Event.COMPLETE) or something like that.
The details are pseudo-sketched out but the idea is to use Flex's bindings to notify view components when changes have been made, and to have shared objects that maintain state. Not sure if that's what you're looking for...
The component LifeCycle does specific stuff in a specific order, and the near final element is to make the component visible.
It sounds to me like you want to defer this setting of visible to true to do other stuff. But, I imaging if you were making use of the component LifeCycle this would be a non-issue.
What sort of app init stuff do you need to do?
I'm trying to remove an eventlistener on (in this specific case) a HorizontalList. The list is initialized with the property
itemRollOver="playPreview(event)"
I'd like to remove this eventListener by switching state and stating something like:
<mx:SetEventHandler target="{horList}" name="itemRollOver" handlerFunction="null" />
This doesn't seem to work. The event is still handled and playPreview(event:ListEvent) is still called. How to properly do this? (I know I can do it in Actionscript, but I specifically want to do it by means of state switching)
Cheers Bart
AFAIK you can only remove listeners that were added with AS, not ones added with mxml. So you should remove the listener from the mxml, on creationComplete of your app use AS to add the event listener, then whatever you do to cause your state to switch can fire an AS function to remove it.
Of the top of my head the code is something like this:
HList.addEventListener(MOUSE_EVENT.RollOver,nameOfRollOverFunction);
HList.removeEventListener(MOUSE_EVENT.RollOver,nameOfRollOverFunction)
I have 2 components for example (editor.mxml using mx:windows), when I click an edit button, I want to get the current value from the other component's datafield? (datagrid.mxml using mx:window)
I do know how to access the main MXML's datagrid by parentDocument or Application.application method, but stumped block if I want to access other way as mentioned above. Keep the code as simple as possible.
You could either do dependency injection, that is, give component A a reference to component B so that they can communicate directly (example of tighter coupling,) or have both components communicate through a common mediator using events (example of more loose coupling.)
Both of those options would be implemented wherever it is that you're creating those components (A and B in this example) and adding them to the display list.
This might be more complicated than it deserves, and it smacks of Pattern-Fever, but you could use a mediator class that listens for the CLICK event from the button and knows enough about the other component to query its property. It could even transmit that data using a custom event, which the button listens for.
While this involves three classes instead of two, it often turns out to be easier to have two components that focus on looking good and one that worries about coordination.
Cheers
Try this:
FlexGlobals.topLevelApplication
This points Your root. From the root You can grab every element You want.
You can also add an id to the custom component like this,
<custom:Editor id="myCustomComponent">
</Editor:AddressForm>
and
access your datagrid's value like this,
var data:ArrayCollection = myCustomComponent.DatagridID.dataProvider;