How to avoid kicking of PropertyChangeEvent for an object until all attributes are assigned in Flex
I want to capture a change in a property of an item as follows
myItem.addEventListener(PropertyChangeEvent.PROPERTY_C开发者_Go百科HANGE,listener);
protected function listener(event:PropertyChangeEvent):void {
...
}
the problem i'm having is that when I assign multiple values to the "myItem" object the listened gets kicked off multiple times. for instance
If I do:
myItem.x = new_x;
myItem.y = new_y;
....
the listener kicks off everytime a change happens (after calling first line, then after calling second line..etc). How to prevent that to save processing/memory and avoid inconsistency.
You can listen for Event.COMPLETE (or create a custom event) and manually dispatch that when you've finished changing all your properties. For example:
myItem.addEventListener(Event.COMPLETE, listener);
protected function listener(e:Event):void
{
...
}
then
myItem.x = newX;
myItem.y = newY;
myItem.dispatchEvent(new Event(Event.COMPLETE));
You can override the setter of your component and dispatch a custom event
You can use mx.utils.ObjectProxy class and by overriding its protected "setupPropertyList" method you can specify by youself what properties will trigger PropertyChangeEvent.PROPERTY_CHANGE event
You could do that the "hackish" way. Example follows...
BindingObject.as:
package bindings
{
import mx.core.EventPriority;
import mx.events.PropertyChangeEvent;
import mx.events.PropertyChangeEventKind;
[Bindable]
public class BindingObject
{
private var inEditMode : Boolean = false;
public function BindingObject()
{
this.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, onPropertyChange, false, EventPriority.BINDING - 1);
}
private function onPropertyChange(event : PropertyChangeEvent) : void
{
if (inEditMode)
event.stopImmediatePropagation();
}
public function beginEdit() : void
{
inEditMode = true;
}
public function endEdit() : void
{
inEditMode = false;
this.dispatchEvent(new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE, false, false, PropertyChangeEventKind.UPDATE));
}
public var myX : int = 0;
public var myY : int = 0;
}
}
testapplication.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="onCreationComplete();">
<mx:Script>
<![CDATA[
import mx.events.PropertyChangeEvent;
import bindings.BindingObject;
[Bindable]
private var something : BindingObject = new BindingObject();
private function onCreationComplete() : void
{
something.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, listener);
something.beginEdit();
trace("Begun edit");
trace("changing myX");
something.myX = 3;
trace("changed myX");
trace("changing myY");
something.myY = 6;
trace("changed myY");
trace("Ending edit");
something.endEdit();
trace("Ended");
}
private function listener(event : PropertyChangeEvent) : void
{
trace("in my listener");
}
private function myX(val : int) : String
{
trace("in myX");
return val.toString();
}
private function myY(val : int) : String
{
trace("in myY");
return val.toString();
}
]]>
</mx:Script>
<mx:Label text="{myX(something.myX)}" />
<mx:Label text="{myY(something.myY)}" />
</mx:Application>
So, as you can see, I've added an event listener in the class to be bound, that will be triggered right after the generated binding listeners (note the priority is BINDING - 1) and in there I stop the propagation of the event. Which means whatever listeners still need to be executed, won't. The endEdit method will dispatch the PropertyChange event that will trigger your listener.
Now, assuming that you do something costly in your listener this should solve your problem.
精彩评论