c# - 使用 ObservableAsPropertyHelper 激活/停用
问题描述
激活/停用与 ObservableAsPropertyHelper 结合的正确用法是什么?给定一个反映长期(热)可观察对象的视图和视图模型,当视图和视图模型被卸载时,订阅需要被释放。然而,建议只读的 ObservableAsPropertyHelper 是在 viewmodel 的构造函数中分配的,不能成为激活/停用生命周期的一部分。处理这种情况的正确方法是什么?
public interface ILongLivedObject
{
IObservable<bool> Status { get; }
}
public class TestViewModel : ReactiveObject
{
private readonly ObservableAsPropertyHelper<bool> _status;
public bool Status => _status.Value;
public TestViewModel(ILongLivedObject obj)
{
_status = obj.Status.ToProperty(this, vm => vm.Status); //how is the subscription disposed?
}
}
在尝试添加取决于此状态的命令时,这也让我陷入了困境。在我的应用程序中,一个常见的用例是让某些硬件处于某种特定状态(例如 IsOpen),并在其为真时允许命令。在不了解的情况下,这就是我想要做的事情:
public class TestViewModel : ReactiveObject
{
private readonly ObservableAsPropertyHelper<bool> _status;
public bool Status => _status.Value;
public ReactiveCommand<Unit, Unit> DoStuff {get;}
public TestViewModel(ILongLivedObject obj)
{
_status = obj.Status.ToProperty(this, vm => vm.Status); //how is the subscription disposed?
DoStuff = ReactiveCommand.CreateFromTask(....., this.WhenAnyValue(this, x => x.Status);
}
}
如果我尝试将 _status 创建移动到 this.WhenActivated 中,则应用程序将崩溃,因为该命令试图在创建状态之前获取它的值。我应该在激活期间(重新)创建命令吗?这似乎是错误的,而且成本很高?
到目前为止,最好有一个带有受保护设置器的常规 Status 属性并在 this.WhenActivated 中进行常规订阅 - 但这是手册告诉避免“只读”属性的内容。
解决方案
所以在反应式编程中需要注意的一件事是,处理通常意味着“取消订阅”。
您通常不需要取消订阅,因为垃圾收集器会为您处理它,只为您创建ObservableAsPropertyHelper
(缩写为OAPH
)从当前 ViewModel 生成的可观察对象。
但是,在您的情况下,您的 observable/object 与当前 ViewModel 之外的对象相关。OAPH 本身是一个 Disposable 对象。
因此,您可以使用ISupportsActivation
(很快会替换IActivableViewModel
)并将您的 OAPH 传递给它的 Disposable 属性。
public class TestViewModel : ReactiveObject, ISupportsActivation
{
private readonly ObservableAsPropertyHelper<bool> _status;
public bool Status => _status.Value;
public ViewModelActivator Activator { get; } = new ViewModelActivator();
public TestViewModel(ILongLivedObject obj)
{
_status = obj.Status.ToProperty(this, vm => vm.Status);
this.WhenActivated(disposables =>
{
disposables(_status);
}
}
}
disposables
传递给lambda的参数WhenActivated
是一个 Func,它接受一个IDisposable
在视图中,确保您派生出IActivatable
(即将重命名IActivatableView
)并在视图的构造函数中使用WhenActivated。
推荐阅读
- python - 如何将 python 日志记录为 Cosmos-DB 记录器?
- xcode - 运行时缺少 SwiftProtobuff.framework
- ios - Swift:隐式返回不编译?
- arrays - 从 bash 脚本中的大型 JSON 输出中提取字符串到数组中
- android - 是否可以同时使用蓝牙和 Wifi 直接发送数据?
- vhdl - 我如何做一个 8 位堆栈?
- mysql - 如何编写这个 SQL(关于日期和时间)?
- php - 如何将值发布到两个不同的 PHP 页面
- angular - 是否可以动态更改 ngbDatepicker 格式化程序?
- python - 使用 OpenCV 恢复图像以增强细节