如何在Flex中分配所有属性之前避免为对象踢入PropertyChangeEvent

时间:2011-02-14 08:45:20

标签: flex

我想捕获项目属性的更改,如下所示

myItem.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,listener);

protected function listener(event:PropertyChangeEvent):void  {
   ...
}

我遇到的问题是,当我为“myItem”对象分配多个值时,被监听的多次被踢掉。例如

如果我这样做:

myItem.x = new_x;
myItem.y = new_y;
....
每次发生变化时(在调用第一行之后,然后在调用第二行......之后),侦听器就会启动。如何防止这种情况以节省处理/内存并避免不一致。

4 个答案:

答案 0 :(得分:1)

您可以覆盖组件的设置器并调度自定义事件

答案 1 :(得分:1)

您可以使用 mx.utils.ObjectProxy 类并重写其受保护的“setupPropertyList”方法,您可以自行指定哪些属性将触发PropertyChangeEvent.PROPERTY_CHANGE事件

答案 2 :(得分:1)

您可以收听Event.COMPLETE(或创建自定义事件),并在您更改完所有属性后手动调度。例如:

myItem.addEventListener(Event.COMPLETE, listener);

protected function listener(e:Event):void
{
   ...
}

然后

myItem.x = newX;
myItem.y = newY;
myItem.dispatchEvent(new Event(Event.COMPLETE));

答案 3 :(得分:1)

你可以用“hackish”方式做到这一点。示例如下......

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>

因此,正如您所看到的,我在要绑定的类中添加了一个事件侦听器,它将在生成的绑定侦听器之后立即触发(注意优先级为BINDING - 1)并且在那里我停止传播这件事。这意味着任何听众仍然需要执行,不会。 endEdit方法将调度将触发侦听器的PropertyChange事件。

现在,假设你在听众中做了一些代价高昂的事,这应该可以解决你的问题。