2016-09-05 2 views
1

Использование Rx У меня есть панель настроек, которая контролирует, включены ли операции и с какой скоростью они должны запускаться. Они хранятся в классе LibrarySettings, когда есть изменение свойства с помощью ползунка/флажка переднего конца, свойство наблюдаемого выбирает изменения.Внедрение класса наблюдаемых настроек

Как написать класс LibrarySettings, чтобы он не устанавливал значение параметра .Value (весь экземпляр 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

+0

Почему вы думаете, что настройка. Значение станет нулевым? –

+0

@BuhBuh Это значение null, когда класс LibrarySettings запускается в первый раз. i.e 'new LibrarySettings (true, 20, true, 30)' установлены свойства enabled и rate, но значение не равно – Mdev

+0

Используете ли вы ReactiveUI? – Shlomo

ответ

2

Во-первых, это не правильный код (обыкновение компилировать)

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

Observable.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 является immuatable.

т.е. либо свойство только для чтения

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;} 
} 

Я только что нашел код, который вы связаны с (вы связаны с корнем репо не реальных классов в вопросе) * https://github.com/markiemarkus/Amadeus/blob/master/Amadeus/NovoApp/Models/LibrarySettings.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; 
    }); 
} 

Вы создаете наблюдаемую последовательность, которая имеет одно значение (так на самом деле не наблюдаемы). Затем вы открываете его через свойство с помощью публичного сеттера (что означает свойство устанавливаемого IObservable?). И, наконец, вы пишете этот экземпляр в своем методе записи, то есть любой, кто фактически подписался на исходное значение свойства, остается в наличии подписки на осирожденную Наблюдаемую последовательность.

1

Если вы просто хотите, чтобы получить за ошибки компиляции, вы выиграете с этим:

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

или это:

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

Похоже, у вас есть большая проблема проектирования что вы еще не выложили.

+0

. Https://github.com/markiemarkus/Amadeus---Copy Однако да, это победа, чтобы пройти мимо ошибки компиляции – Mdev

+0

Возврат 'Одноразовый.Empty' является такой плохой анти-шаблон. Я бы настоятельно рекомендовал ОП, чтобы они избегали этого конкретного варианта «Observable.Create». – Enigmativity

+0

Почему антипаттерн? Эти два функционально эквивалентны. – Shlomo