在Matlab依赖的观察特性。 它的工作原理?(Dependent observable pro

2019-07-30 15:03发布

在Matlab的类这似乎是语法正确财产申报是依赖 (计算不存储)和可观察的同时。 考虑代码

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

这是否按预期方式工作? 也就是说,如果属性propertyOne存储在对象的instanceOfAnotherClass改变是有由触发属性更改事件propertyTwo ? 需要注意的是propertyOne是无法观测

编辑:它不工作(如我所料)。 “后集”事件不会被触发。 那么,如何应对这种情况? 有没有更好的解决方案,然后创建propertyTwo作为非依赖并将其设置为相同的值“propertyOne”每次“propertyOne”的变化?

EDIT2:在反应荷银的 他的回答的编辑 ,我将解释的情况更加复杂。 考虑此2类:

 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

使用这些代码的类不应该访问AClass 。 它只能与实例交互BClass ,想听听性质的变化b 。 但是如果我让物业aAClass观察到,不会解决我的问题,不是吗? 在“后集”的事件不会传播到物业b ,是吗?

Answer 1:

这可能是语法正确,但听者回调将不会执行。 例:

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

现在试试:

c = MyClass();
lh = addlistener(c, 'b', 'PostSet',@(o,e)disp(e.EventName));
c.a = 1;
disp(c.b)

正如你看到的永远不会执行“后集”的回调。


编辑

我看到它的方式, SetObservable真的应该设定ab 。 它因为b是只读和可如果只改变a变化。 现在, PostSet事件将及时通知我们,这两个特性发生了改变。

使用I上面使用的相同的例子,简单地移动SetObservableba 。 当然,现在你听的事件为:

lh = addlistener(c, 'a', 'PostSet',@(o,e)disp(e.EventName));

编辑#2

对不起,我没注意这样的事实,你必须组成(BClass具有ACLASS的实例作为私有财产)。

考虑这种可能的解决方案:

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

基本上,我们设置属性a ACLASS作为观察的。

接下来BClass的构造函数中,我们注册传递给侦听财产ACLASS实例的侦听a变化。 在回调,我们通知此对象的听众, b也改变了

既然我们不能真正提高一个PostSet手动,我创建了一个自定义事件bPostSet这是我们在前面的回调函数提高。 您可以随时通过定制的事件数据,参考文档 ,看看如何。

下面是测试情况:

%# create the objects
a = AClass();
b = BClass(a);

%# change property a. We will not recieve any notification
disp('a.a = 1')
a.a = 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('a.a = 2')
a.a = 2;

%# remove event handler
delete(lh)

%# no more notifications
disp('a.a = 3')
a.a = 3;

输出是:

a.a = 1
a.a = 2
-- changed
a.a = 3

请注意,当我们注册了监听器与BClass情况如何,我们只进行交互。 当然,因为所有的类派生自handle类,实例a和私有财产aClassInst都指向同一个对象。 所以任何修改aa立即上反映b.aClassInst.a ,这将导致内部aPostSet_EventHandler来执行,这反过来又通知所有已注册侦听到我们的自定义事件。



文章来源: Dependent observable property in Matlab. Does it work?