It may be syntactically correct, but the listener callback will never be executed. Example:
classdef MyClass < handle properties (Access = public) a end properties (SetAccess = private, Dependent, SetObservable) b end methods function val = get.b(this) val = this.a; end end end
Now try:
c = MyClass(); lh = addlistener(c, 'b', 'PostSet',@(o,e)disp(e.EventName)); ca = 1; disp(cb)
As you can see, the PostSet callback is never executed.
EDIT
The way I see it, SetObservable
really should be set to a
not b
. Because b
is read-only and can only change when a changes. Now the PostSet
event will tell us that both properties are changed.
Use the same example that I used above, just move SetObservable
from b
to a
. Of course, now you are listening to the event as:
lh = addlistener(c, 'a', 'PostSet',@(o,e)disp(e.EventName));
EDIT # 2
Sorry, I didn’t pay attention to the fact that you have a composition (BClass has an instance of AClass as private).
Consider this possible solution:
AClass.m
classdef AClass < handle properties (SetObservable) a %
BClass.m
classdef BClass < handle properties (Access = private) aClassInst %# instance of AClass lh %# event listener on aClassInst.a end properties (Dependent, SetAccess = private) b %# dependent property, read-only end events (ListenAccess = public, NotifyAccess = private) bPostSet %# custom event raised on b PostSet end methods function this = BClass(aClass) %# store AClass instance handle this.aClassInst = aClass; %# listen on PostSet event for property a of AClass instance this.lh = addlistener(this.aClassInst, 'a', ... 'PostSet', @this.aPostSet_EventHandler); end function val = get.b(this) val = this.aClassInst.a; end end methods (Access = private) function aPostSet_EventHandler(this, src, evt) %# raise bPostSet event, notifying all registered listeners notify(this, 'bPostSet') end end end
We basically set the property of a
AClass as observable.
Next, inside the BClass constructor, register a listener for the AClass instance passed to listen for changes to property a
. In the callback, we notify listeners of this object that b
also changed
Since we cannot actually create a PostSet
manually, I created a custom bPostSet
event, which we raise in the previous callback function. You can always set up event data, see the Documentation to find out how to do this.
Here is an example:
%# create the objects a = AClass(); b = BClass(a); %# change property a. We will not recieve any notification disp('aa = 1') aa = 1; %# now lets listen for the 'bChanged' event on b lh = addlistener(b, 'bPostSet',@(o,e) disp('-- changed')); %# try to change the property a again. We shall see notification disp('aa = 2') aa = 2; %# remove event handler delete(lh) %# no more notifications disp('aa = 3') aa = 3;
The output was:
aa = 1 aa = 2 -- changed aa = 3
Please note that we only interact with the BClass instance when registering our listener. Of course, since all classes are derived from the handle
class, the instance of a
and the private property aClassInst
refer to the same object. Therefore, any changes in aa
immediately reflected in b.aClassInst.a
, this leads to the execution of an internal aPostSet_EventHandler
, which, in turn, notifies all registered listeners of our user event.