这里是我的例子:
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)