2016-01-05 12 views
6

Sto esplorando Rx e volevo vedere se potevo definire in modo dichiarativo l'input e l'output di alcuni elementi dell'interfaccia utente in termini reciproci, prima che il componente di questo elemento fosse inizializzato.C'è un modo per spingere dichiaratamente gli aggiornamenti ad un osservabile dopo che è stato definito?

Questo è quello che sarebbe simile:

class ViewController: UIViewController { 
    @IBOutlet weak var button: UIButton! 

    var child: ButtonComponent! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let buttonInput = PublishSubject<()>() 
     let buttonOutput = buttonInput 
      .scan(0) { count, _ in 
       count + 1 
      } 
      .map { $0.description } 

     self.child = ButtonComponent(
      button: self.button, 
      input: buttonInput, 
      output: buttonOutput 
     ) 
    } 
} 

class ButtonComponent { 
    weak var button: UIButton! 
    let disposeBag = DisposeBag() 

    init(button: UIButton, input: PublishSubject<()>, output: Observable<String>) { 
     self.button = button 

     output 
      .subscribeNext { string in 
       button.setTitle(string, forState: .Normal) 
      } 
      .addDisposableTo(disposeBag) 

     button.rx_tap 
      .subscribeNext { 
       input.onNext($0) 
      } 
      .addDisposableTo(disposeBag) 
    } 
} 

Il problema qui è che sto usando il PublishSubject per spingere gli aggiornamenti al flusso di input, che è di importanza fondamentale e sconsigliati. Rx fornisce un modo per aggiungere in qualche modo sequenze ad un osservabile già in esecuzione?

+1

risposta alla sua ultima domanda è sì, utilizzando 'Observable.Merge'. Anche se non sono abbastanza sicuro di come applicarlo qui ... – supertopi

risposta

0

Dopo alcune ricerche, la risposta sembra essere no. Semplicemente perché se vuoi aggiungere una sequenza a un osservabile già in esecuzione, è una mutazione. E non c'è un modo dichiarativo di fare una mutazione.

Ho esaminato una libreria javascript denominata cycle.js che fa esattamente la stessa cosa e l'hanno risolta in modo simile, con un oggetto ReplaySubject.

L'unica cosa che puoi fare è farlo sembrare un po 'più bello facendo

button.rx_tap 
    .subscribe(input) 

Invece di

button.rx_tap 
    .subscribeNext { 
     input.onNext($0) 
    } 
+0

Questo non è vero. L'operatore 'merge' ti permetterà di aggiungere a un osservabile già in esecuzione. – Enigmativity

+0

'merge' restituisce un nuovo osservabile, non può mutare un osservabile. – mschumacher

+0

Sì, ma se si inserisce l'unione nella query in fase di compilazione, è possibile inserire i valori in fase di esecuzione. – Enigmativity

Problemi correlati