如何在ReactiveUI中使用WhenAny(...)合并多个可观察对象? [英] How do I merge several observables using WhenAny(...) in ReactiveUI?

查看:225
本文介绍了如何在ReactiveUI中使用WhenAny(...)合并多个可观察对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,是对该网站提出的以下问题的扩展.

I have a question which is an extension of the following question raised on this site.

我有一个IObservable<Unit>(让我们说X),一个反应式集合(Y)和一个属性(Z).返回类型并不重要.我只想在这些更改中的任何一个订阅.

I have an IObservable<Unit> (lets say X), a reactive collection (Y) and a property (Z). Return type is not important. I just want to subscribe when any of these change.

我知道如何使用Observable.Merge如下观察所有3和Subscribe.

I know how to observe all 3 and Subscribe using Observable.Merge as below.

Observable.Merge(X, Y.Changed, ObservableForProperty(Z).Select(_ => Unit.Default)).Subscribe(..)

它有效.

但是,当我尝试使用WhenAny(...,....,....).Subscribe()时,当我的X更改时,订阅不会被触发.使用WhenAny(...)而不是Observable.Merge(..)进行上述操作的语法是什么?

However, when I try to use WhenAny(...,....,....).Subscribe(), the subscribe does not get triggered when my X changes. What is the syntax for doing the above using WhenAny(...) rather than Observable.Merge(..)??

我更喜欢使用WhenAny(....),因为我在其他地方使用ReactiveUI.

I prefer to use WhenAny(....) because I am using ReactiveUI in other places.

示例: 说我有一个从ReactiveObject派生的类,它具有以下属性.

Example: Say I've got a class derived from ReactiveObject with following properties.

public class AnotherVM : ReactiveObject
{
    public bool IsTrue
    {
        get { return this.isTrue; }
        set { this.RaiseAndSetIfChanged(x => x.isTrue, ref this.isTrue, value); }
    }

    public IObservable<Unit> Data
    {
        get { return this.data; }
    }

    public ReactiveCollection MyCol
    {
       get { return Mycol; }
    }    
}

public class MyVM : ReactiveObject
{
    MyVM
    {
       // do WhenAny or Observable.Merge here....
    }
}

我想使用MyVM类中的Observable.Merge(..)WhenAny(...)来观察AnotherVM类中的以上属性.我发现,当三个属性中的任何一个发生更改时,当我在MyVM中使用WhenAny(...)Merge(...)订阅上述内容时,并不会总是收到通知.

I want to observe the above properties in AnotherVM class using Observable.Merge(..) or WhenAny(...) in MyVM class. I found that I do not always get a notification when I subscribe to the above in MyVM using WhenAny(...) or Merge(...) when either of the 3 properties change.

推荐答案

WhenAny不是用于监视任意可观察对象集,而是用于监视ReactiveUI支持的对象的属性(例如ReactiveObject或反应性集合).

WhenAny is not for monitoring across sets of arbitrary observables, it's for monitoring the properties of an object supported by ReactiveUI (like a ReactiveObject or reactive collection).

对于将可观察流中的更改合并在一起的一般情况,Observable.Merge是正确的方法.

For the general case of combining changes in observable streams, Observable.Merge is the right way to go.

编辑

我注意到您已声明Data和MyCol属性为只读.如果您使用这样的Merge:

I note that you have declared the Data and MyCol properties read only. If you use a Merge like this:

Observerable.Merge(this.WhenAnyValue(o=>o.IsTrue, v=>Unit.Default),
                   this.Data,
                   this.MyCol.CollectionChanged.Select(v=>Unit.Default))

...然后您必须注意不要更改背景字段.如果这样做,那么您将丢失事件-也许这是正在发生的事情?

...then you must be careful not to change the backing fields. If you do, then you will get missing events - maybe this is what is happening?

在这种情况下,您需要将这些属性连接到RaiseAndSetIfChanged并使用Switch进行跟踪-例如如果this.data可以更改,那么您将需要(我在这里使用ReactiveUI 5 + .NET 4.5,以防RaiseAndSetIfChanged语法看起来很奇怪):

In that case you would need to wire up those properties to RaiseAndSetIfChanged and use a Switch to keep track - e.g. if this.data could change then you would need (I'm using ReactiveUI 5 + .NET 4.5 here in case the RaiseAndSetIfChanged syntax looks odd):

public IObservable<Unit> Data
{
    get { return this.data; }
    private set { this.RaiseAndSetIfChanged(ref data, value); }
}

您的合并将类似于:

Observerable.Merge(this.WhenAnyValue(o=>o.IsTrue, v=>Unit.Default),
                   this.WhenAnyObservable(x => x.Data),
                   this.MyCol.CollectionChanged.Select(v=>Unit.Default))

WhenAnyObservable在概念上与此等效:

WhenAnyObservable is conceptually equivalent to this:

WhenAny(x => x.Data, vm => vm.Value).Switch()

使用切换到Data的最新值.不要忘记使用设置器来更改数据值!

using Switch to flip over to the latest value of Data when it changes. Don't forget to use the setter to change values of data!

这篇关于如何在ReactiveUI中使用WhenAny(...)合并多个可观察对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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