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.I have found 2 options to fix this:
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.
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.