Dependent observable property in Matlab. It works?

In the Matlab class, it seems syntactically correct to declare the Dependent property (computed not saved) and Observable at the same time. Consider the code

properties (Access = private) instanceOfAnotherClass end properties (SetAccess = private, Dependent, SetObservable) propertyTwo end methods function val = get.propertyTwo(this) val = this.instanceOfAnotherClass.propertyOne; end end 

Does this work as expected? That is, if the propertyOne propertyOne object stored in instanceOfAnotherClass is changed, is there a property change event caused by propertyTwo ? Note that propertyOne not observable.

Edit: This does not work (as I expected). The PostSet event does not fire. So how can I handle this situation? Is there a better solution for creating propertyTwo as independent and assigning it a value of "propertyOne" with every change to "propertyOne"?

Edit2: In response to Amro, edit his answer. I will explain the situation more complicated. Consider two classes:

  classdef AClass < handle properties a end end classdef BClass < handle properties (Access = private) aClassInst end properties (Dependent, SetObservable, SetAccess = private) b end methods function this = BClass(aClass) this.aClassInst = aClass; end function val = get.b(this) val = this.aClassInst.a; end end end 

A class that uses all this code should not access AClass . It only interacts with the BClass instance and wants to listen for changes to property b . however, if I make the a of AClass observable, that will not solve my problem, will it? 'PostSet' events do not extend to property b , are they?

+6
source share
1 answer

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 %# observable property end end 

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.

+3
source

Source: https://habr.com/ru/post/921314/


All Articles