2011-11-04 19 views
7

Tengo un modelo de vista ReactiveUI-like. Tiene varias propiedades de diferentes tipos que activan los eventos NotifyPropertyChanged y quiero suscribir un método que se invocará cuando se active alguno, pero no estoy interesado en los valores reales.¿Existe una forma más elegante de combinar observables cuando el tipo de devolución no es importante?

Mi código actual es un poco feo (debido a true opaco selecciona). ¿Hay alguna manera de expresar esto que muestre la intención de cuidar solo cuando ocurre el evento?

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

estoy fusión de alrededor de 8 propiedades, por lo que es más feo que se muestra.

Respuesta

16

Dado que esto se parece a ReactiveUI, cómo sobre el uso del operador WhenAny:

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

En general, sin embargo, si Combinando observaciones arbitrarias, también podría escribir esto un poco más claramente utilizando el método sin extensión:

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 => /* ... */); 

Además, si usted está suscribiendo a todas las propiedades de un ReactiveObject, probablemente es mejor usar simplemente:

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

no es realmente reactivo, la propiedad observable es solo mi método de extensión que diferencia el nombre y devuelve observable del patrón de evento PropertyChanged. Además, no se suscribe a todas las propiedades, solo algunas de ellas. –

+0

WhenAny parece genial, sin embargo, como entiendo por la sintaxis, todavía no ignora los valores reales. –

+0

WhenAny funciona como Zip, especifica una función de selector como último parámetro; en este caso, estamos seleccionando a Unit –

2

que podría hacer que un método de extensión para hacer el intento más claro:

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

sí podía hacerlo. Si no hay una mejor alternativa, probablemente lo haga de esta manera o establezca ObservableForPropertyIgnoreValue en su lugar. Sin embargo, en este caso estamos creando un valor observable que no está comunicando nuestra intención de no utilizarlo muy bien, lo cual no es muy bonito, creo. Sin embargo, debemos observar algo, ¿supongo que no debe haber una mejor manera? –

+9

el tipo [Unidad] (http://msdn.microsoft.com/en-us/library/system.reactive.unit (v = vs.103) .aspx), que comunicará que el valor devuelto no tiene ningún valor Aparte de que existe –

+0

+1 a la sugerencia de Scott, en lugar de 'verdadero', use 'Unidad.Defecto' –

Cuestiones relacionadas