سؤال

I have an interface IBaseInterface and a class BaseClass.

When I refer to BaseClass via the IBaseInterface type the bindings with event names won't fire. However the normal binding (without event name) fires.

If I refer to BaseClass with Object or BaseClass types all is OK and the bindings fire.

IBaseInterface:

[Event(name="propTwoChanged", type="flash.events.Event")]
[Event(name="propThreeChanged", type="flash.events.Event")]

[Bindable]

public interface IBaseInterface extends IEventDispatcher{

    function get propOne() :Number;
    function set propOne(value:Number) :void;

    [Bindable(event="propTwoChanged")]
    function get propTwo() :Number;

    [Bindable(event="propThreeChanged")]
    function get propThree() :Number;

}

BaseClass:

[Event(name="propTwoChanged", type="flash.events.Event")]
[Event(name="propThreeChanged", type="flash.events.Event")]

[Bindable]

public class BaseClass extends EventDispatcher implements IBaseInterface{

    private var _propOne:Number = 0;
    public function get propOne() :Number{
        return _propOne;
    }
    public function set propOne(value:Number) :void{
        _propOne = value;
        dispatchEvent(new Event('propTwoChanged'));
        dispatchEvent(new Event('propThreeChanged'));
    }

    [Bindable(event="propTwoChanged")]
    public function get propTwo() :Number{
        return propOne * 2;
    }

    [Bindable(event="propThreeChanged")]
    public function get propThree() :Number{
        return propOne / 2;
    }

}

So, to clarify the problem:

  • propTwo and propThree bindings on IBaseInterface do not fire.
  • propOne binding is OK, this does not have an event name.
  • The problem only occurs when accessing via the interface, other types are OK.
هل كانت مفيدة؟

المحلول

I have found 2 options to fix this:

Option 1

Defining a single [Bindable(event="...")] metadata on the interface (not on the function signatures), and then dispatching a single event to update all properties on the interface.

IBaseInterface:

[Event(name="updateBindings", type="flash.events.Event")]
[Bindable(event="updateBindings")]
public interface IBaseInterface extends IEventDispatcher{

    function get propOne() :Number;
    function set propOne(value:Number) :void;

    function get propTwo() :Number;

    function get propThree() :Number;

}

BaseClass:

[Event(name="updateBindings", type="flash.events.Event")]
[Bindable(event="updateBindings")]
public class BaseClass extends EventDispatcher implements IBaseInterface{

    private var _propOne:Number = 0;
    public function get propOne() :Number{
        return _propOne;
    }
    public function set propOne(value:Number) :void{
        _propOne = value;
        dispatchEvent(new Event('updateBindings'));
    }

    public function get propTwo() :Number{
        return propOne * 2;
    }

    public function get propThree() :Number{
        return propOne / 2;
    }

}

This is a little clumsy I think, if there are a lot of properties or a lot of listeners in the view then it would be too resource intensive.


Option 2

Defining a single [Bindable] (without event) on the interface, and then from the class directly dispatching a PropertyChangeEvent.

IBaseInterface:

[Bindable]
public interface IBaseInterface extends IEventDispatcher{

    function get propOne() :Number;
    function set propOne(value:Number) :void;

    function get propTwo() :Number;

    function get propThree() :Number;

}

BaseClass:

[Bindable]
public class BaseClass extends EventDispatcher implements IBaseInterface{

    private var _propOne:Number = 0;
    public function get propOne() :Number{
        return _propOne;
    }
    public function set propOne(value:Number) :void{
        _propOne = value;
        dispatchEvent(new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE, true, true, PropertyChangeEventKind.UPDATE, 'propTwo'));
        dispatchEvent(new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE, true, true, PropertyChangeEventKind.UPDATE, 'propThree'));
    }

    public function get propTwo() :Number{
        return propOne * 2;
    }

    public function get propThree() :Number{
        return propOne / 2;
    }

}

This way is best I think, it is less intensive than option 1 because only the required properties are updated. It also cleans up the code, most metadata can be removed from the class and interface.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top