Matlab中依赖的可观察属性。它工作吗 [英] Dependent observable property in Matlab. Does it work?

查看:260
本文介绍了Matlab中依赖的可观察属性。它工作吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Matlab类中,在同一时间内声明依赖(计算未存储)和可观察属性似乎是语法正确的。考虑代码

In Matlab class it seems to be syntactically correct to declare property that is Dependent (computed not stored) and Observable in the same time. Consider 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

这是否按预期工作?也就是说,如果存储在 instanceOfAnotherClass 中的对象的属性 propertyOne 更改了由 propertyTwo ?请注意, propertyOne 不是可观察

Does this work as expected? That is, if the property propertyOne of an object stored in instanceOfAnotherClass is changed is there property change event triggered by propertyTwo? Note that propertyOne is not Observable.

编辑:
它不工作(正如我预期的)。 'PostSet'事件不被触发。那么我该怎么处理这种情况呢?是否有一个更好的解决方案,然后创建 propertyTwo 作为一个非依赖,并将其设置为与propertyOne相同的值每次propertyOne更改?

It does not work (as I expected). 'PostSet' event is not triggered. So how do I deal with this kind of situation? Is there a better solution then to create propertyTwo as a non Dependent and set it to the same value as 'propertyOne' every time 'propertyOne' changes?

Edit2:
反应 Amro的 他的答案编辑我会解释情况比较复杂。
考虑这两个类:

In reaction to Amro's edit of his answer I will explain situation more complex. Consider this 2 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

使用这一切的类代码不应该访问 AClass 。它只与 BClass 的实例进行交互,并希望收听属性 b 的更改。但是,如果我将属性 a AClass 可观察到,这不会解决我的问题,是吗? PostSet事件不会传播到属性 b ,是吗?

The class that uses all this code should not get access to AClass. It interacts only with instance of BClass and wants to listen to changes of property b. however if I make property a of AClass observable that would not solve my problem, would it? The 'PostSet' events are not going to propagate to property b, are they?

推荐答案

它可能在语法上是正确的,但是听众回调永远不会执行。示例:

It might be syntactically correct, but the listener callback will never execute. 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

现在尝试:

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

正如你可以看到'PostSet'回调永远不会执行。

As you can see the 'PostSet' callback is never executed.

我看到的方式 SetObservable 应该设置在 a 而不是 b 。它因为 b 是只读的,只有在 a 更改时才会更改。现在, PostSet 事件将通知我们两个属性都已更改。

The way I see it, SetObservable should really be set on a not b. Its because b is read-only and can only change if a changes. Now the PostSet event would notify us that both properties have changed.

使用上面所使用的相同示例将 SetObservable b 移动到 a 。当然现在你会听到这个事件:

Use the same example I used above, simply move SetObservable from b to a. Of course now you listen to the event as:

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






编辑#2



对不起,我没有注意到你有组合的事实(BClass有一个AClass作为私有属性的实例)。


EDIT#2

Sorry I didn't pay attention to the fact that you have composition (BClass has an instance of AClass as private property).

这个可能的解决方案:

classdef AClass < handle
    properties (SetObservable)
        a                        %# observable property
    end
end



BClass.m



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

基本上我们将AClass的属性 a 可见。

Basically we set property a of AClass as observable.

下面在BClass的构造函数中,我们注册传递给监听属性 a 的AClass实例的侦听器更改。在回调中,我们通知这个对象的听众, b 也有变化

Next inside the constructor of BClass, we register a listener for the AClass instance passed to listen on property a changes. In the callback we notify listeners of this object that b has changed as well

既然我们不能真的提高一个 PostSet 手动,我创建了一个自定义事件 bPostSet ,我们在以前的回调函数中提出。您可以随时自定义传递的事件数据,请参阅文档看看如何。

Since we can't really raise a PostSet manually, I created a custom event bPostSet which we raise in the previous callback function. You can always customize the event data passed, refer to the documentation to see how.

这是一个测试用例:

%# 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 class,实例 a 和私有属性 aClassInst 都指同一个对象。所以对 aa 的任何更改立即反映在 b.aClassInst.a 中,这将导致内部 aPostSet_EventHandler 执行,然后通知所有注册的监听器到我们的自定义事件。

Notice how we only interact with the BClass instance when we register our listener. Of course since all classes derive from handle class, the instance a and the private property aClassInst both refer to the same object. So any changes to a.a are immediately reflected on b.aClassInst.a, this causes the internal aPostSet_EventHandler to execute, which in turn notify all registered listeners to our custom event.

这篇关于Matlab中依赖的可观察属性。它工作吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆