2011-11-04 8 views
7

Mam model widoku podobnego do ReactiveUI. Ma kilka właściwości różnych typów, które wywołują zdarzenia NotifyPropertyChanged i chcę subskrybować metodę, która będzie wywoływana, gdy jakikolwiek zostanie uruchomiony, ale nie interesują mnie rzeczywiste wartości.Czy istnieje bardziej elegancki sposób łączenia obserwowalnych, gdy typ zwracany jest nieważny?

Mój obecny kod jest nieco brzydki (z powodu nieprzezroczystych wyborów true). Czy istnieje sposób, aby wyrazić to, co pokazuje intencję tylko opieki, gdy wydarzenie ma miejsce?

this.ObservableForProperty(m => m.PropertyOne) 
     .Select(_ => true) 
     .Merge(this.ObservableForProperty(m => m.PropertyTwo).Select(_ => true)) 
    .Subscribe(...) 

Łączę około 8 właściwości, więc jest bardziej brzydka niż pokazano.

Odpowiedz

16

Ponieważ wygląda ReactiveUI, jak o użyciu operatora WhenAny:

this.WhenAny(x => x.PropertyOne, x => x.PropertyTwo, (p1, p2) => Unit.Default) 
    .Subscribe(x => /* ... */); 

Generalnie jednak, jeśli łączono arbitralne obserwacje, można również napisać to nieco wyraźniej, stosując metodę nierozszerzania:

Observable.Merge(
    this.ObservableForProperty(x => x.PropertyOne).Select(_ => Unit.Default), 
    this.ObservableForProperty(x => x.PropertyTwo).Select(_ => Unit.Default), 
    this.ObservableForProperty(x => x.PropertyThree).Select(_ => Unit.Default) 
).Subscribe(x => /* ... */); 

Ponadto, jeśli subskrypcji każdej majątku ReactiveObject, to chyba lepiej po prostu użyć:

this.Changed.Subscribe(x => /* ... */); 
+0

Naprawdę nie reactiveui, obserwowalna właściwość to tylko moja metoda rozszerzenia, która wymusza nazwę i zwraca obserwowalne z właściwości PropertyChanged. Nie subskrybujesz każdej nieruchomości, tylko niektóre z nich. –

+0

WhenAny wygląda fajnie, jednak jak rozumiem na podstawie składni nadal nie ignoruje rzeczywistych wartości. –

+0

Kiedy Any działa jak Zip, określasz funkcję selektora jako ostatni parametr - w tym przypadku wybieramy Unit –

2

Można zrobić to metodę rozszerzenia aby intencją wyraźniej:

public static IObservable<bool> IgnoreValue<T>(this IObservable<T> source) 
{ 
    return source.Select(_ => true); 
} 

... 

this.ObservableForProperty(m => m.PropertyOne).IgnoreValue() 
.Merge(this.ObservableForProperty(m => m.PropertyTwo).IgnoreValue()) 
.Subscribe(..); 
+0

tak mógłby zrobić. Jeśli nie ma lepszej alternatywy, prawdopodobnie zrobiłoby to w ten sposób, lub zamiast tego uczyniłoby ObservableForPropertyIgnoreValue. Jednak w tym przypadku tworzymy wartość obserwowalną , która nie komunikuje naszego zamiaru, aby nie używać jej bardzo dobrze, co nie jest zbyt piękne, jak sądzę. Musimy jednak obserwować coś, co wydaje mi się, że nie może być lepszego sposobu? –

+9

typu [Jednostka] (http://msdn.microsoft.com/en-us/library/system.reactive.unit (v = vs.103) .aspx), który poinformuje, że zwracana wartość nie ma wartości poza tym, że istnieje –

+0

+1 do sugestii Scotta, zamiast "true", użyj "Unit.Default" –

Powiązane problemy