激活/停用与 ObservableAsPropertyHelper 的正确用法是什么?给定反射(reflect)长期(热)可观察对象的 View 和 View 模型,订阅将需要在卸载 View 和 View 模型时处理。但是,建议只读的 ObservableAsPropertyHelper 在 View 模型的构造函数中分配,并且不能成为激活/停用生命周期的一部分。处理此类情况的正确方法是什么?
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 中,应用程序将崩溃,因为命令试图在它创建之前获取状态值。我应该在激活期间(重新)创建命令吗?这似乎是错误的,而且成本很高?
到目前为止,拥有一个带有 protected setter 的常规 Status 属性并在 this.WhenActivated 中进行常规订阅似乎更好 - 但这是手册告诉要避免的“只读”属性。
最佳答案
所以在 Reactive 编程中需要注意一件事,处置通常意味着“取消订阅”。
您通常不需要取消订阅,因为垃圾收集器会为您处理,为您提供仅生成可观察对象的 ObservableAsPropertyHelper
(缩写为 OAPH
)来自当前的 ViewModel。
然而,在您的情况下,您的可观察对象/对象与当前 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);
}
}
}
传递到 WhenActivated
lambda 的 disposables
参数是一个采用 IDisposable
的 Func
在 View 中,确保派生自 IActivatable
(即将重命名为 IActivatableView
)并在 View 的构造函数中使用 WhenActivated。
关于c# - 使用 ObservableAsPropertyHelper 激活/停用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56033281/