2016-04-27 20 views
5

Le implementazioni di rx forniscono BehaviorSubject<T> e Variable<T> come meccanismi per la modellazione delle proprietà che cambiano nel tempo (un utile sostituto per C# INotifyPropertyChanged).Esiste un'interfaccia BehaviorSubject di sola lettura in RX e in caso contrario, è una cattiva idea crearne una?

Generalmente questi sono esposti come Observable<T> ma sarebbe più utile per presentare le proprietà come qualcosa di simile:

class ObservableValue<T> : Observable<T>{ 
    var currentValue:T { get } 
} 

Questo può essere creato in questo senso in rapida:

class ObservableValue<Element> : ObservableType { 

    typealias E = Element 

    private let subject:BehaviorSubject<E> 

    var currentValue:E { 
     get { 
      return try! subject.value() 
     } 
    } 

    init(subject:BehaviorSubject<E>) { 
     self.subject = subject 
    } 

    func subscribe<O: ObserverType where O.E == E>(observer: O) -> Disposable { 
     return self.subject.subscribe(observer) 
    } 

}

Esiste già? e se no è perché è contro gli obiettivi di Rx?

L'unico modo intorno ad esso è quello di esporre un CurrentValue separata o scrivere consumatori che assumono l'attuazione concreta dietro l'esposto osservabile è un BehaviourSubject o da qualche parte nella catena un replay() si è verificato ad esempio il seguente frammento non rende esplicito che non appena mi iscrivo mi metterò un valore:

class MyViewModel { 
    // 'I will notify you of changes perhaps including my current value' 
    myProperty:Observable<String> 
} 

così codice deve essere scritto come se il suo 'asincrono' un presupposto di fondo che agirà in maniera quasi modo sincrono anziché:

class MyViewModel { 
    // 'I have a current value and will notify you of changes going forward' 
    myProperty:ObservableValue<String> 
} 

risposta

1

aver pensato sopra e discusso un po 'più presumibilmente la ragione non (e forse non dovrebbe esistere) è che è una presentazione dello stato imperativamente letta.

Altri meccanismi di mantenimento dello stato (ad esempio scan) lo fanno entro i confini degli osservabili concatenati piuttosto che come chiamate dirette "senza uscita" come "datemi il valore in questo momento".

Forse avrebbe il suo posto in un approccio ibrido reattivo/imperativo, ma potrebbe solo ostacolare il completo abbraccio dello stile reattivo.

È analogo utilizzare promesse o attività a metà del codice, quindi ripristinare il codice di blocco sincrono in altre parti.

0

Nella maggior parte dei casi ciò che le persone fanno è creare un modello di visualizzazione standard che espone le proprietà tramite INotifyPropertyChanged. Ciò consente agli elementi dell'interfaccia utente di collegarsi a loro e ricevere eventi di modifica delle proprietà e mantenere l'interfaccia utente in sincronia.

Quindi, se si desidera un IObile per tale proprietà, si avvantaggiano gli operatori Rx standard che trasformano gli eventi in IObservable. Puoi google per trovare molte diverse implementazioni. Generalmente si creano e si consumano questi osservabili da qualcosa che sta osservando il modello di vista invece di esporli direttamente sul modello di vista.

+0

Ciò funzionerebbe in Rx.NET perché si dispone di INotifyPropertyChanged ma in rapido non lo si fa (il più vicino è KVO, che è solo su sottoclassi NSObject). Inoltre, non sono sicuro che mi piaccia l'idea di esporre un get/set, un INotifyPropertyChanged e un Observable da qualche parte - se sto facendo il viewmodel perché non l'ho appena fatto con osservabili piuttosto che mixare sistemi di eventi. – Cargowire