2016-01-05 17 views
6

Eksploruję Rx i chciałem sprawdzić, czy mogę zadeklarować dane wejściowe i z jakiegoś elementu UI względem siebie, zanim ten składnik elementu zostanie zainicjowany.Czy istnieje sposób deklaratywnego przekazywania aktualizacji do obserwowalnego po zdefiniowaniu?

To co to będzie wyglądać:

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

Problem polega na tym, że używam PublishSubject do pchania aktualizacje do strumienia wejściowego, co jest konieczne i odradzane. Czy Rx zapewnia sposób na dodanie sekwencji do już działających obserwowalnych?

+1

Odpowiedź na ostatnie pytanie brzmi: tak, za pomocą 'Observable.Merge'. Chociaż nie jestem całkiem pewien, jak zastosować go tutaj ... – supertopi

Odpowiedz

0

Po pewnych badaniach odpowiedź wydaje się być nie. Po prostu dlatego, że jeśli chcesz dodać sekwencję do już działającego obserwowalnego, jest to mutacja. I nie ma deklaratywnego sposobu na mutację.

Spojrzałem na bibliotekę javascript o nazwie cycle.js, która robi dokładnie to samo, a oni rozwiązali ją w podobny sposób, z ReplaySubject.

Jedyne co można zrobić, to sprawić wrażenie nieco ładniejszy wykonując

button.rx_tap 
    .subscribe(input) 

Zamiast

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

To nie jest prawda. Operator 'merge' pozwoli ci dodać do już działającego obserwowalnego. – Enigmativity

+0

'merge' zwraca nowe obserwowalne, nie może zmutować obserwowalnego. – mschumacher

+0

Tak, ale jeśli wstawisz merge do zapytania podczas kompilacji, możesz wstawić wartości w czasie wykonywania. – Enigmativity

Powiązane problemy