ReactiveUI - WhenActivated and Output Properties

只愿长相守 提交于 2019-12-13 03:46:27

问题


I'm using ReactiveUI and I'm trying to change all my ViewModels' rules with WhenActivated but I'm unable understand how to have it working well in conjunction with output properties.

The pattern is something like

this.WhenActivated(
registerDisposable =>
{
    registerDisposable(this.Bind(…));
    registerDisposable(this.WhenAny(…));
    registerDisposable(this.WhenAnyValue(…));
});

and the output properties looks like

protected readonly ObservableAsPropertyHelper<object> _Obj;
public object Obj => _Obj.Value
_Obj = this.WhenAnyValue(x => x.Something).ToProperty(this, x => x.Obj, out _Obj);

So the only way I see to unite these is:

class MyClass {

protected readonly ObservableAsPropertyHelper<object> _Obj;
public object Obj => _Obj.Value

public MyClass()
{
    _Obj = this.WhenAnyValue(x => x.Something).ToProperty(this, x => x.Obj, out _Obj);

    this.WhenActivated( registerDisposable =>
    {
        registerDisposable(_Obj);
    });
}

}

Will this work as expected or there is another better way to do it?


回答1:


In this case, _Obj doesn't need to be disposed of because Something has the same scope as _Obj (they're both contained within MyClass). However, if you were to base _Obj off of an observable contained in a service - which commonly has a longer lifetime than a view model - then you'd need to dispose of it.

// _Obj should be disposed of, in this case.
_Obj = someService
    .SomePipeline
    .ToProperty(this, x => x.Obj)

Side note: you don't need to use the out parameter if you're assigning to a value. The following is equivalent to the above:

someService
    .SomePipeline
    .ToProperty(this, x => x.Obj, out _Obj)

So in the case of someService, you could put _Obj inside WhenActivated but it

creates sticky race conditions whereby the OAPH may be null when it's corresponding property (Obj) is accessed too early.

This info, as well as the quote above, is taken straight from Kent Boogaart's book, "You, I, and ReactiveUI."

He was kind enough to provide a solution for the above scenario that turns activation into a pipeline. You can use these extensions (the first for view models and the second for views) like this:

_Obj = this
    .GetIsActivated()
    .Select(isActivated => isActivated ? someService.SomePipeline : Observable.Return(null))
    .Switch()
    .ToProperty(this, x => x.Obj);


来源:https://stackoverflow.com/questions/50999799/reactiveui-whenactivated-and-output-properties

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!