实现一个可观察的设置类



使用Rx,我有一个设置面板,控制操作是否启用以及它们应该以什么速率运行。这些都存储在LibrarySettings类中,当通过前端滑块/复选框对属性进行更改时,可观察属性会根据更改进行拾取。

我应该如何编写LibrarySettings类,使它不设置设置。值(整个LibrarySettings实例)为null。

IDisposable reader = setting.Value.Subscribe(options =>
{
    OperationOneEnabled = options.OperationOneEnabled;
    OperationTwoEnabled = options.OperationTwoEnabled;
    OperationOneRate = options.OperationOneRate;
    OperationTwoRate = options.OperationTwoRate;     
});
IDisposable writer = this.WhenAnyPropertyChanged()
    .Subscribe(vm =>
    {
        settings.Write(new LibrarySettings(OperationOneEnabled, OperationOneRate,
            OperationTwoEnabled, OperationTwoRate));
    });
OperationOneRateProperty = this.WhenValueChanged(vm => vm.ScheduleRate)
    .DistinctUntilChanged()
    .Select(value => $"{value} seconds")
    .ForBinding();
 _CleanUp = new CompositeDisposable(reader, writer, OperationOneRateProperty);

所以在LibrarySettings类中我需要创建属性

public IObservable<LibrarySettings> Value
{
    get { return _Value; }
    set { _Value = value; }
}

所以我尝试下面的

Value = Observable.Create<LibrarySettings>(() =>
{
    new LibrarySettings(false, OperationOneEnable,OperationOneRate,
        OperationTwoEnabled, OperationTwoRate);
});

并得到

delegate func<IObserver<LibrarySettings>> does not take 0 arguments

首先,这不是有效的代码(不会编译)

Value = Observable.Create<LibrarySettings>(() =>
{
    new LibrarySettings(false, OperationOneEnable,OperationOneRate,
        OperationTwoEnabled, OperationTwoRate);
});

可观测。Create通常使用Func<IObserver<T>, IDisposable>作为参数,因此应修改为

Value = Observable.Create<LibrarySettings>(observer =>
{
    observer.OnNext(new LibrarySettings(/*args*/));
    //What to do here?
    return Disposable.Empty; //Yuck.
});

可能更好和更简单的是只使用Observable.Return,但什么是可观察到的。看起来它使用Rx只是为了满足一个签名,因为这并不符合Rx的精神。

相反,我认为你真正想要的是一个Settings属性,当它改变时推送通知。为此,我认为有两种合理的方法

  1. 你有一个LibrarySettings的只读属性,LibrarySettings类型是可变的和可观察的。
  2. 你有一个可变和可观察的LibrarySettings属性,但LibrarySettings类型是不可变的。

。readonly属性

this.Setting.WhenAnyPropertyChanged()....
this.Setting.OperationOneRate = 25;
this.Setting.IsOperationOneEnabled= true;

类型是可变的

public class LibrarySettings : INotifyPropertyChanged
{
    public LibrarySettings()
    {
        IsOperationOneEnabled = false;;
        OperationOneRate = 0;
        IsOperationTwoEnabled = false;
        OperationTwoRate = 0;
    }
    public bool IsOperationOneEnabled { get;set; }
    public double OperationOneRate { get; set; }
    public bool IsOperationTwoEnabled { get;set; }
    public double OperationTwoRate { get; set;}
    #region INPC Impl
    #region
}

或者不可变类型,并且您改变属性(每次使用一个新实例)。显然,您希望使用默认值创建它。

this.WhenValueChanges(t=>t.Setting)....
this.Setting = new LibrarySettings(OperationOneEnable, OperationOneRate,
    OperationTwoEnabled, OperationTwoRate);

还有…

public class LibrarySettings
{
    public LibrarySettings(bool isOperationOneEnabled, double operationOneRate,
        bool isOperationTwoEnabled, double operationTwoRate)
    {
        IsOperationOneEnabled = isOperationOneEnabled;
        OperationOneRate = operationOneRate;
        IsOperationTwoEnabled = isOperationTwoEnabled;
        OperationTwoRate = operationTwoRate;
    }
    public bool IsOperationOneEnabled { get; }
    public double OperationOneRate { get; }
    public bool IsOperationTwoEnabled { get; }
    public double OperationTwoRate { get;}
}

我刚刚找到了你链接到的代码(你链接到repo的根,而不是实际的类)* https://github.com/markiemarkus/Amadeus/blob/master/Amadeus/NovoApp/Models/LibrarySettings.cs

  • https://github.com/markiemarkus/Amadeus/blob/master/AmadeusNovoApp/Models/View/LibraryOptionsViewModel.cs

主要问题是这几行

Value = Observable.Create<LibrarySettings>(observer =>
{
    observer.OnNext(new LibrarySettings(false, OperationOneEnabled, OperationOneRate, OperationTwoEnabled, OperationTwoRate));
    return Disposable.Empty;
});  

}

public IObservable<LibrarySettings> Value
{
     get { return _Value; }
     set { _Value = value; }
}
public void Write(LibrarySettings item)
{
     Value = Observable.Create<LibrarySettings>(observer =>
    {
        observer.OnNext(new LibrarySettings(false, OperationOneEnabled,
        OperationOneRate, OperationTwoEnabled, OperationTwoRate));
        return Disposable.Empty;
    });
}

你创建了一个可观察序列,它只有一个值(所以不是真正的可观察序列)。然后你通过一个带有公共setter的属性公开它(一个可设置的IObservable属性是什么意思?!)最后,在write方法中重写该实例,这意味着任何实际上订阅了该属性的原始值的人都保留了对孤立的Observable Sequence的订阅。

如果您只是想克服编译错误,那么您可以使用以下代码:

Value = Observable.Return(new LibrarySettings(/*args*/));

或:

Value = Observable.Create<LibrarySettings>(observer =>
{
    observer.OnNext(new LibrarySettings(/*args*/));
    return Disposable.Empty;
});

听起来你有一个更大的设计问题,但你还没有列出。

相关内容

  • 没有找到相关文章

最新更新