我有一个可观察的
//trying to reset state
componentWillUnmount(){
this.setState({click: 0})
}
以lazy var user = _user.share(replay: 1)
private let _user = PublishRelay<User>()
单身。应用加载后,我的UserState.swift
可观察对象就会收到一个事件,并且我会从后端收到一个用户。
稍后,在我的一个ViewModel中,我尝试
user
除非此事件永远不会触发(不要进入闭包内部),因为func profileViewModel(
viewAppeared: Observable<Void>
) -> (
title: Observable<String>
) {
let title = viewAppeared.withLatestFrom(UserState.shared.user) { _, user in
user.username
}
return title
}
在被订阅之前就已经触发了。
在user
事件中,我从可观察的事件中获取最新的viewDidLoad
值时,如何实现此行为?
编辑:
在我的单例初始化中,如果我随机插入一个user
,那么这一切都可行。我很困惑...
答案 0 :(得分:1)
我看到了问题。 PublishRelay基本上只是一个PublishSubject。
viewModel订阅之前推送的所有内容都将丢失。 .share(replay:1)会有所帮助,不同之处在于在将用户推送到那个之前,需要订阅一些东西给那个,以便它“捕获”事件并为它缓存值以后的订阅者。
即使那样,您可能仍需要.share(重播:1,范围:.forever)。
您需要记住,您可以设置所需的所有可观察链,但是该链中的任何操作都不会执行,直到最终订阅该链。
将您的用户状态更改为BehaviorSubject
然后在您的视图模型上执行以下操作。
class ProfileViewModel {
lazy var user = UserState.shared.user.compactMap { $0 }
lazy var name = user.map { $0.username }
lazy var age = user.map { "\($0.age) years old" }
.do(onNext: { print($0) }
// etc
}
class profileViewController {
...
override func viewDidLoad() {
...
profileViewModel.name
.subscribe(onNext: { [weak self] name in
self?.title = name
}
.disposed(by: disposeBag)
}
}
请注意,如果在此视图控制器显示期间用户(以及用户名)可以动态更改,并且您希望标题自动更新,则需要这样做。
还要注意,如图所示,您永远不会在.do语句中看到用户的年龄,因为当前没有任何订阅或绑定到该可观察的子链。