我正在尝试了解如何在RxUi 7中使用Interaction<TInput, TOutput>
来显示确认提醒。在阅读docs之后,我提出了这个问题:
视图模型
public ReactiveCommand<Unit, Unit> Save { get; }
public Interaction<Exception, bool> ConfirmError;
Save
.ThrownExceptions
.Subscribe(ex => ConfirmError
.Handle(ex)
.Where(retry => retry == true)
.SelectMany(_ => Save.Execute(Unit.Default))
.Subscribe()
.AddTo(disposables))
.AddTo(disposables);
查看
this
.ViewModel
.ConfirmError
.RegisterHandler(async interaction =>
{
var retry = await DisplayAlert("Confirm",
$"Something went wrong: {interaction.Input.Message}. Do you want to retry?",
"Yes",
"No");
interaction.SetOutput(retry);
})
.AddTo(disposables);
我的代码正在运行,但我不确定在确认完成后是否正确执行了命令。我也认为这对于一个简单的警报框来说代码太多了,我正在寻找一种合适的方法来实现它。 怎么可以简化呢?
第二个问题是:
如果我需要处理多个Exception
类型(即:服务错误,连接错误),哪里是检查它的正确位置?
答案 0 :(得分:1)
我认为你的代码大部分没问题,除了一件事 - 你正在另一个Subscribe
内进行Subscribe
调用,这是一个代码味道。要摆脱它,你可以写下这样的东西:
Save
.ThrownExceptions
.SelectMany(ConfirmError.Handle)
.Where(retry => retry == true)
.SelectMany(_ => Save.Execute(Unit.Default))
.Subscribe()
.AddTo(disposables);
使用InvokeCommand
helper:
Save
.ThrownExceptions
.SelectMany(ConfirmError.Handle)
.Where(retry => retry == true)
.Select(_ => Unit.Default)
.InvokeCommant(Save)
.AddTo(disposables);
N.B。我没有玩RxUI 7.0,所以我将流改为包含单位的流是一个疯狂的猜测。
我还认为这对于一个简单的警报框而言代码太多了
嗯,这是一个警告框和一个重试逻辑。我不确定你是否能比RxUI更简单。
如果我需要处理多个异常类型(即:服务错误,连接错误),哪里是检查它的正确位置?
就个人而言,我不会考虑异常类型,而是考虑您希望与实际用户进行交互的方式。毕竟,你可能不想向他展示堆栈跟踪。
这样做的一种方法是针对不同类型的用户(Interactions
,MessageInteraction
等)进行不同类型的互动YesNoInteraction
,这样可以让您区分例如需要用户输入和Toast消息的动作。另一种方法是将所有可能的问题定义为枚举(ConnectionTimeout
,ServiceError
等),将可能的解决方案定义为另一个(Retry
,Abort
,... 。)然后在ViewModel中有一个Interaction<ProblemEnum, ResolutionEnum>
。这样,处理错误的代码将存储在一个地方。这种方法的缺点是处理逻辑将在View中,因此测试起来会更加困难。
我建议您尝试并报告我的想法在实践中如何运作:)