如何从 Repository > ViewModel > Fragment 传播 Livedata
How to propagate Livedata from Repository > ViewModel > Fragment
getMoreData()
在 ViewModel 中从 ViewModel 外部调用,每次用户滚动到 RecyclerView 的底部。
fetchMore()
存储库 returns 具有 LoadingStatus
对象的 LiveData,其中包含 loading/success/failure 和错误消息
如何在 ViewModel 中设置 loadingStatus
变量,以便 Fragment 可以正确观察到它?
注意:ViewModel 中的 getMoreData()
可以在用户向下滚动时调用多次。
ViewModel{
val loadingStatus
fun getMoreData(){
repository.fetchMore()
}
}
Repository{
fun fetchMore() : LiveData<LoadingStatus>{
}
}
Fragment{
viewModel.loadingStatus.observe()
}
问题在于需要 Lifecycle Owner 用于观察存储库中的 LiveData。
首先,您不想在每次调用 fetchMore()
时都 return 一个新的 LiveData<LoadingStatus>
。每次都会创建一个新的 LiveData。最好的情况是,您希望函数 fetchMore()
执行类似这样的操作,更新单个 LiveData:
Repository{
val status = LiveData<LoadingStatus>()
fun fetchMore() {
status.postValue(LOADING)
// Pseudo code for actually loading more items
status.postValue(FINISHED LOADING)
}
}
但是,您会遇到从 ViewModel
观察 status
的问题,因为它本身不是 Lifecycle 实现,因此它不能轻易地从 Repository 观察 LiveData。
我的建议是这样的:
ViewModel{
val loadingStatus: MutableLiveData<LoadingStatus>
init{
repository.observeStatus()
.subscribe( event -> loadingStatus.postValue(event))
}
fun getMoreData(){
repository.fetchMore()
}
}
Repository{
val status = BehaviorSubject.create<LoadingStatus>()
fun observeStatus(): Observable<LoadingStatus> {
return status
}
fun fetchMore(){
status.onNext(LOADING)
// Pseudo code for actually loading more items
status.onNext(FINISHED LOADING)
}
}
Fragment{
viewModel.loadingStatus.observe()
}
请注意,您必须在 ViewModel onCleared 中处理订阅。
请注意,所有这些都是伪代码,应该比这更干净。
getMoreData()
在 ViewModel 中从 ViewModel 外部调用,每次用户滚动到 RecyclerView 的底部。
fetchMore()
存储库 returns 具有 LoadingStatus
对象的 LiveData,其中包含 loading/success/failure 和错误消息
如何在 ViewModel 中设置 loadingStatus
变量,以便 Fragment 可以正确观察到它?
注意:ViewModel 中的 getMoreData()
可以在用户向下滚动时调用多次。
ViewModel{
val loadingStatus
fun getMoreData(){
repository.fetchMore()
}
}
Repository{
fun fetchMore() : LiveData<LoadingStatus>{
}
}
Fragment{
viewModel.loadingStatus.observe()
}
问题在于需要 Lifecycle Owner 用于观察存储库中的 LiveData。
首先,您不想在每次调用 fetchMore()
时都 return 一个新的 LiveData<LoadingStatus>
。每次都会创建一个新的 LiveData。最好的情况是,您希望函数 fetchMore()
执行类似这样的操作,更新单个 LiveData:
Repository{
val status = LiveData<LoadingStatus>()
fun fetchMore() {
status.postValue(LOADING)
// Pseudo code for actually loading more items
status.postValue(FINISHED LOADING)
}
}
但是,您会遇到从 ViewModel
观察 status
的问题,因为它本身不是 Lifecycle 实现,因此它不能轻易地从 Repository 观察 LiveData。
我的建议是这样的:
ViewModel{
val loadingStatus: MutableLiveData<LoadingStatus>
init{
repository.observeStatus()
.subscribe( event -> loadingStatus.postValue(event))
}
fun getMoreData(){
repository.fetchMore()
}
}
Repository{
val status = BehaviorSubject.create<LoadingStatus>()
fun observeStatus(): Observable<LoadingStatus> {
return status
}
fun fetchMore(){
status.onNext(LOADING)
// Pseudo code for actually loading more items
status.onNext(FINISHED LOADING)
}
}
Fragment{
viewModel.loadingStatus.observe()
}
请注意,您必须在 ViewModel onCleared 中处理订阅。
请注意,所有这些都是伪代码,应该比这更干净。