我有一个ViewModel
,其中有一些ReactiveCommands
用户可以手动调用。
CommandA
CommandB
CommandC
因此,用户只能先调用 B 或 A ,然后再调用 C 。
问题在于,我想创建另一个命令来按顺序运行它们(从A到C)。它们不应该并行运行,而是顺序 >。
如何命令给定特征?
答案 0 :(得分:3)
由于您希望它们顺序执行,因此ReactiveCommand.CreateCombined
并不是一个很好的选择。但是,您可以创建类似于CombinedReactiveCommand的内容以适合您的情况。
可以通过调用ReactiveCommand<TParam,TResult>.Execute
手动执行反应性命令,该方法返回一个返回单个值的IObservable<TResult>
。因此,一个非常基本的实现可以通过SelectMany
将其链接到其他执行调用:
ReactiveCommand.CreateFromObservable(() =>
CommandA.Execute()
.SelectMany(_ => CommandB.Execute())
.SelectMany(_ => CommandC.Execute()));
如果所有命令都具有相同的类型,则可以使其更通用:
var commands = new[] { CommandA, CommandB, CommandC };
ReactiveCommand.CreateFromObservable(() =>
commands.Aggregate(
Observable.Return(Unit.Default),
(acc, cur) => acc.SelectMany(_ => cur.Execute())));
但是,这没有考虑CombinedReactiveCommand处理的其他内容,例如CanExecute
和ThrownExceptions
。如果需要处理这些问题,则可以考虑使用自己的CombinedReactiveCommand。
答案 1 :(得分:1)
导入System.Reactive.Linq,现在您可以:
{
await CommandA.Execute();
await CommandB.Execute();
await CommandC.Execute();
}
System.Reactive.Linq使IObservable处于等待状态。
答案 2 :(得分:0)
我正在假设您的命令的类型为ReactiveCommand<Unit,Unit>
,因此,您可以执行以下操作:
public class MyCoolViewModel
{
bool runSequentially = false;
public ReactiveCommand<Unit, Unit> Command { get; set; }
public ReactiveCommand<Unit, Unit> Command2 { get; set; }
public ReactiveCommand<Unit, Unit> Command3 { get; set; }
public ReactiveCommand<Unit, Unit> CommandwhoInvokesOtherCommands { get; set; }
public MyCoolViewModel()
{
Command = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
{
runSequentially= false;
Console.WriteLine("Start 1");
await Task.Delay(1000);
Console.WriteLine("End 1");
return Unit.Default;
});
Command2 = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
{
runSequentially = false;
Console.WriteLine("Start 2");
await Task.Delay(1000);
Console.WriteLine("End 2");
return Unit.Default;
});
Command3 = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
{
Console.WriteLine("Start 3");
await Task.Delay(1000);
Console.WriteLine("End 3");
return Unit.Default;
});
CommandwhoInvokesOtherCommands = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
{
Console.WriteLine("Invoking other commands");
runSequentially = true;
await Task.Delay(1000);
Console.WriteLine("End");
return Unit.Default;
});
/*Command 1, 2 and 3 only will run if flag is set to true*/
CommandwhoInvokesOtherCommands.Where(_ => runSequentially).InvokeCommand(Command);
Command.Where(_ => runSequentially).InvokeCommand(Command2);
Command2.Where(_ => runSequentially).InvokeCommand(Command3);
//Observable.Return(Unit.Default).InvokeCommand(CommandwhoInvokesOtherCommands);//for test purposes
}
}
实用程序方法InvokeCommand将在命令返回时调用另一个命令,因此该方法加上where子句即可解决问题。
希望对您有所帮助 问候