从 RxUi 7 中的视图与 ThrownExceptions 交互的正确方法
Proper way to interact with ThrownExceptions from the view in RxUi 7
我正在尝试了解如何在 RxUi 7 中使用 Interaction<TInput, TOutput>
来显示确认警报。阅读 docs 之后,我想到了这个:
ViewModel
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
类型(即:服务错误、连接错误),检查它的正确位置在哪里?
我认为您的代码基本上没问题,除了一件事 - 您正在另一个 Subscribe
中进行 Subscribe
调用,IMO 是一种代码味道。要摆脱它,您可以这样写:
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,所以我将流更改为包含单元的流是一个大胆的猜测。
I also think it´s way too much code for a simple alert box
嗯,这是一个警告框和一个重试逻辑。我不确定你是否可以在 RxUI 中使用它比这更简单。
If I need to handle more than one Exception type (ie: service error, connection error), where is the right place to check it?
就个人而言,我不会考虑 exception 类型,而是考虑您希望与实际用户交互的方式。毕竟,您可能不想向他显示堆栈跟踪。
一种方法是为不同类型的用户交互(MessageInteraction
、YesNoInteraction
等)单独 Interactions
,这将允许您区分例如需要用户输入和 toast 消息的操作。另一种方法是将所有可能的问题定义为枚举(ConnectionTimeout
、ServiceError
等),将可能的解决方案定义为另一个问题(Retry
、Abort
、.. .) 然后在你的 ViewModel 中有一个 Interaction<ProblemEnum, ResolutionEnum>
。这样,处理错误的代码将存储在一个地方。这种方法的缺点是处理逻辑将在视图中,因此测试起来会困难得多。
我建议您尝试并报告我的想法在实践中的效果:)
我正在尝试了解如何在 RxUi 7 中使用 Interaction<TInput, TOutput>
来显示确认警报。阅读 docs 之后,我想到了这个:
ViewModel
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
类型(即:服务错误、连接错误),检查它的正确位置在哪里?
我认为您的代码基本上没问题,除了一件事 - 您正在另一个 Subscribe
中进行 Subscribe
调用,IMO 是一种代码味道。要摆脱它,您可以这样写:
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,所以我将流更改为包含单元的流是一个大胆的猜测。
I also think it´s way too much code for a simple alert box
嗯,这是一个警告框和一个重试逻辑。我不确定你是否可以在 RxUI 中使用它比这更简单。
If I need to handle more than one Exception type (ie: service error, connection error), where is the right place to check it?
就个人而言,我不会考虑 exception 类型,而是考虑您希望与实际用户交互的方式。毕竟,您可能不想向他显示堆栈跟踪。
一种方法是为不同类型的用户交互(MessageInteraction
、YesNoInteraction
等)单独 Interactions
,这将允许您区分例如需要用户输入和 toast 消息的操作。另一种方法是将所有可能的问题定义为枚举(ConnectionTimeout
、ServiceError
等),将可能的解决方案定义为另一个问题(Retry
、Abort
、.. .) 然后在你的 ViewModel 中有一个 Interaction<ProblemEnum, ResolutionEnum>
。这样,处理错误的代码将存储在一个地方。这种方法的缺点是处理逻辑将在视图中,因此测试起来会困难得多。
我建议您尝试并报告我的想法在实践中的效果:)