Apache flex 在Flex中分配所有属性之前,如何避免对象的PropertyChangeEvent被踢出

Apache flex 在Flex中分配所有属性之前,如何避免对象的PropertyChangeEvent被踢出,apache-flex,Apache Flex,我希望捕获项的属性中的更改,如下所示 myItem.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,listener); protected function listener(event:PropertyChangeEvent):void { ... } 我遇到的问题是,当我为“myItem”对象指定多个值时,侦听的对象会被多次启动。比如说 如果我这样做: myItem.x = new_x; myItem.y = new_y

我希望捕获项的属性中的更改,如下所示

myItem.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,listener);

protected function listener(event:PropertyChangeEvent):void  {
   ...
}
我遇到的问题是,当我为“myItem”对象指定多个值时,侦听的对象会被多次启动。比如说

如果我这样做:

myItem.x = new_x;
myItem.y = new_y;
....

每次更改发生时,侦听器都会启动(在调用第一行之后,然后在调用第二行之后..等等)。如何防止这种情况,以节省处理/内存并避免不一致

您可以覆盖组件的setter并分派自定义事件

您可以覆盖组件的setter并分派自定义事件

您可以使用mx.utils.ObjectProxy类并通过覆盖其受保护的“setupPropertyList”方法您可以指定哪些属性将触发PropertyChangeEvent.PROPERTY\u CHANGE event

您可以使用mx.utils.ObjectProxy类,并通过重写其受保护的“setupPropertyList”方法,您可以指定哪些属性将触发PropertyChangeEvent.PROPERTY\u CHANGE event

您可以侦听事件。完成(或创建自定义事件)并在完成所有属性更改后手动分派。例如:

myItem.addEventListener(Event.COMPLETE, listener);

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


您可以侦听Event.COMPLETE(或创建自定义事件),并在完成所有属性的更改后手动分派该事件。例如:

myItem.addEventListener(Event.COMPLETE, listener);

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

你可以用“黑客”的方式来做。下面是一个例子

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事件,该事件将触发您的侦听器

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

你可以用“黑客”的方式来做。下面的例子

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事件,该事件将触发您的侦听器

现在,假设您在侦听器中做了一些代价高昂的事情,这应该可以解决您的问题