通常情况下,ReactiveCommand
必须对UI中的数据进行操作,这些数据可以适应IObservable
。每次触发命令时,它都应对数据源进行采样并对其执行操作。
IObservable<CommandContext> context = ... ;
Command = ReactiveCommand.Create();
context.Sample(Command).Subscribe(c => CommandImpl(c));
问题是,当上下文没有改变时,Sample
不会重新采样。我试图使用 Repeat
来解决这个问题,但由于 Rx 是咄咄逼人的而不是懒惰的,它会导致锁定。
contextSelect(c => Observable.Repeat(c)).Switch()
.Sample(Command)
.Subscribe(c => CommandImpl(c));
你需要的是一个WithLatestFrom()
的方法。它有许多Rx版本,但遗憾的是没有在最新的正式版本的 Rx.NET(2.2.5)中。
如果你有它,你的代码可能看起来像这样:
Command
.WithLatestFrom(context, (_, ctx) => ctx))
.Subscribe(ctx => CommandImpl(ctx));
幸运的是,此运算符似乎已添加到最新的预发行包 Rx.NET (2.3.0-beta2) 中。
或者,您可以使用上面链接的 github 问题中提供的实现之一 - 例如 James World 的这个(注意 - 我没有测试它):
public static IObservable<TResult> WithLatestFrom<TLeft, TRight, TResult>(
this IObservable<TLeft> source,
IObservable<TRight> other,
Func<TLeft, TRight, TResult> resultSelector)
{
return other.Publish(os =>
source.SkipUntil(os)
.Zip(os.MostRecent(default(TRight)), resultSelector));
}