如何从存储库> ViewModel>片段传播Livedata

时间:2018-09-13 08:10:26

标签: kotlin android-architecture-components android-livedata

每当用户滚动到RecyclerView的底部时,都会从ViewModel外部调用ViewModel中的

getMoreData()

存储库中的

fetchMore()返回带有LoadingStatus对象的LiveData,其中包含加载/成功/失败和错误消息

如何在ViewModel中设置loadingStatus变量,以便Fragment可以正确观察它?

注意:当用户向下滚动时,可以多次调用ViewModel中的getMoreData()

ViewModel{
    val loadingStatus

    fun getMoreData(){
        repository.fetchMore()
    }
}

Repository{
    fun fetchMore() : LiveData<LoadingStatus>{

    }
}

Fragment{
    viewModel.loadingStatus.observe()
}

1 个答案:

答案 0 :(得分:1)

问题在于需要使用生命周期所有者来观察存储库中的LiveData。

首先,您不想每次调用LiveData<LoadingStatus>时都返回一个新的fetchMore()。那样每次都会创建一个新的LiveData。最好的情况是,您希望函数fetchMore()做这样的事情,更新单个LiveData:

Repository{
    val status = LiveData<LoadingStatus>()

    fun fetchMore() {
        status.postValue(LOADING)

        // Pseudo code for actually loading more items

        status.postValue(FINISHED LOADING)
    }
}

但是,您将遇到从status观察ViewModel的问题,因为它本身不是生命周期实现,因此它无法轻松地从存储库中观察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中处置订阅。
请注意,所有这些都是伪代码,应该比这更清洁。