从Rxswift订阅后不接收最后一个值

时间:2018-07-11 03:03:08

标签: swift

这里是我的例子:

class AViewModel: BaseViewModel {
    private let venueSubject: BehaviorRelay<VenueDetails>
    private let venueObservable: Observable<VenueDetails>

    let venueMapViewModel: VenueMapViewModel

    init(venue: VenueDetails) {
       self.venueSubject = BehaviorRelay(value: venueDetails)
       self.venueObservable = self.venueSubject.asObservable().share()

       venueMapViewModel = VenueMapViewModel(
        venueObservable: self.venueObservable
       )
    }

    //My view will call this at some point
    func loadVenue() {
       APIRepo
           .getVenueDetails()
           .do(onSuccess: { [weak self] (venue) in
              self?.venueSubject.accept(venue)
           })
           .asCompletable()
           .subscribe(onCompleted: nil, onError: { [weak self] (error) in
              print(error)
           })
           .disposed(by: disposeBag)
    }
}


class VenueMapViewModel: BaseViewModel {
    let venueLocationViewModel: VenueLocationViewModel

    init(venueObservable: Observable<VenueDetails>) {        
       venueLocationViewModel = VenueLocationViewModel(venueObservable: venueObservable)
    }
}

class VenueLocationViewModel: BaseViewModel {
    private let venueObservable: Observable<VenueDetails>

    init(venueObservable: Observable<VenueDetails>) {
       self.venueObservable = venueObservable
    }

    lazy var addressObseravable: Observable<String> = { venueObservable.share().map({ (venue) -> String in venue.address?.formattedAddress() ?? "" }) }()

    //My view have a button which will triger this
    func venueLocationView() {

        //It will never go to `onNext`
        self.venueObservable.take(1)
            .subscribe(onNext: { (venue) in
               print("success")
            }, onError: { (error) in
               print("error")
            })
            .disposed(by: self.disposeBag)
    }
}

class VenueLocationView: BaseView {

    @IBOutlet weak var btnAddress: UIButton!

    //INFO - Assum my code bind the view when I link ViewModel with my View
    override func bind() {
      super.bind()

    //button get the last version of the Venue
      (viewModel as? VenueLocationViewModel)?
        .addressObseravable
        .bind(to: btnAddress.rx.title(for: .normal))
        .disposed(by: self.disposeBag)

      btnAddress.rx.tap.asObservable()
        .subscribe(onNext: { [weak self] _ in
            //use can click and call `venueLocationView`
            (self?.viewModel as? VenueLocationViewModel)?.venueLocationView(isTapButton: true)
        })
        .disposed(by: disposeBag)
}

我成功地使其与额外的BehaviorRelay一起使用,但是我不喜欢该实现

class VenueLocationViewModel: BaseViewModel {
    private let venueSubject: BehaviorRelay<VenueDetails> = BehaviorRelay(value: VenueDetails())

    init(venueObservable: Observable<VenueDetails>) {
       super.init()
       venueObservable
        .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
        .subscribe(onNext: { (venue) in
           self.venueSubject.accept(venue)
        }, onError: { (error) in
            reportError("impossible get venue - error: \(error)")
        })
        .disposed(by: self.disposeBag)
    }

    lazy var addressObseravable: Observable<String> = { venueSubject.asObservable().share().map({ (venue) -> String in venue.address?.formattedAddress() ?? "" }) }()

    //My view have a button which will triger this
    func venueLocationView() {

        //it go on `onNext`
         self.venueSubject.take(1).asObservable()
             .subscribe(onNext: { (venue) in
                 print("success")
             }, onError: { (error) in
                 print("error")
             })
             .disposed(by: self.disposeBag)
    }
}

您能解释一下为什么第一个例子不起作用吗?

更新:发现了问题

self.venueObservable = self.venueSubject.asObservable().share()呢,我必须将其更改为self.venueObservable = self.venueSubject.asObservable().share(replay: 1, scope: .forever)

0 个答案:

没有答案