Rx 如何将命令与另一个可观察对象结合起来

Rx how to combine command with another observable

我有一些响应式命令以及一些包含一些信息的可观察对象,我正在尝试做类似的事情:

_navigate = ReactiveCommand.Create(CanNavigate);
_navigate.CombineLatest(navigationTarget, (_, tgt) => tgt)
    .Subscribe(tgt => Navigation.NavigateTo(tgt));

我尝试了几种不同的方法:

  1. SelectMany
  2. Zip

我要么结束:

  1. 订阅在第一次后停止调用(如果我使用 Zip)
  2. 即使命令执行一次后还没有执行,订阅也会调用

基本上我想要:

An observable that triggers every time (and only) when the command has been executed, along with pulling in the most recent value of the second observable.

无法完全理解如何最好地实现这一目标...

如果您能够使用预发布版本,最新的 (2.3.0-beta2) 有方法 WithLatestFrom 正是这样做的。

_navigate.WithLatestFrom(navigationTarget, (_, tgt) => tgt)
  .Subscribe(tgt => Navigation.NavigateTo(tgt));

如果没有,您可以通过以下方式创建自己的:

public static IObservable<TResult> WithLatestFrom<TLeft, TRight, TResult>(
    this IObservable<TLeft> source,
    IObservable<TRight> other,
    Func<TLeft, TRight, TResult> resultSelector)
{
    return source.Publish(os =>
        other.Select(a => os
            .Select(b => resultSelector(b,a)))
            .Switch());
}

Source

我们使用 Join 来实现此行为。

想法是,某一时刻你有一个 window 用于 navigtion target 而没有 window 用于 _navigate 命令。当命令出现时,它从另一个序列的当前打开 window 中获取值。当新的 navigationTarget 到达时,navigationTarget 值的 window 关闭。

_navigate.Join(
    navigationTarget,
    _ => Observable.Empty<Unit>(),
    _ => navigationTarget,
    (_, tgt) => tgt).Subscribe(tgt => Navigation.NavigateTo(tgt));