android - 在 Repository 和 ViewModel 之间共享相同的 MutableLiveData
问题描述
我正在考虑架构组件/MVVM。
假设我有一个存储库、一个 ViewModel 和一个 Fragment。我使用一个Resource
类作为包装器来公开网络状态,就像架构组件指南中所建议的那样。
我的存储库目前看起来像这样(为简洁起见进行了简化):
class MyRepository {
fun getLists(organizationId: String) {
var data = MutableLiveData<Resource<List<Something>>>()
data.value = Resource.loading()
ApolloClient().query(query)
.enqueue(object : ApolloCall.Callback<Data>() {
override fun onResponse(response: Response<Data>) {
response.data()?.let {
data.postValue(Resource.success(it))
}
}
override fun onFailure(exception: ApolloException) {
data.postValue(Resource.exception(exception))
}
})
}
然后在 ViewModel 中,我还声明了一个 MutableLiveData:
var myLiveData = MutableLiveData<Resource<List<Something>>>()
fun getLists(organizationId: String, forceRefresh: Boolean = false) {
myLiveData = myRepository.getLists(organizationId)
}
最后,片段:
viewModel.getLists.observe(this, Observer {
it?.let {
if (it.status.isLoading()) showLoading() else hideLoading()
if (it.status == Status.SUCCESS) {
it.data?.let {
adapter.replaceData(it)
setupViews()
}
}
if (it.status == Status.ERROR) {
// Show error
}
}
})
如您所见,观察者没有被触发会出现问题,因为 LiveData 变量将在过程中被重置(存储库创建一个新实例)。
我试图找出确保在 Repository 和 ViewModel 之间使用相同的 LiveData 变量的最佳方法。
我考虑过将 ViewModel 中的 LiveData 传递给 getLists 方法,以便存储库使用 ViewModel 中的对象,但即使它有效,这样做似乎也是错误的。
我的意思是这样的:
视图模型
var myLiveData = MutableLiveData<Resource<List<Something>>>()
fun getLists(organizationId: String, forceRefresh: Boolean = false) {
myRepository.getLists(myLiveData, organizationId)
}
存储库
fun getLists(data: MutableLiveData<Resource<List<Something>>>, organizationId: String) {
...
}
解决方案
我想我知道该怎么做,感谢@NSimon 的提示。
我的存储库保持不变,我的 ViewModel 如下所示:
class MyViewModel : ViewModel() {
private val myRepository = MyRepository()
private val organizationIdLiveData = MutableLiveData<String>()
private val lists = Transformations.switchMap(organizationIdLiveData) { organizationId -> myRepository.getLists(organizationId) }
fun getLists() : LiveData<Resource<MutableList<Something>>> {
return lists
}
fun fetchLists(organizationId: String, forceRefresh: Boolean = false) {
if (organizationIdLiveData.value == null || forceRefresh) {
organizationIdLiveData.value = organizationId
}
}
}
getLists()
我在我的片段中观察,并viewModel.fetchLists(id)
在需要数据时调用。似乎是合法的?
推荐阅读
- c - 谁定义了栈指针地址
- c# - 我的部分视图未从我所在区域内的正确文件位置加载
- typescript - 键入一个方法,该方法返回一个具有此属性的对象?
- angular - 为什么在使用 FormBuilder 重置表单时出现验证错误?
- python - 来自生成器的张量流数据集
- bash - 将数字输入 mkdir
- javascript - 导入的函数在 render() 下不起作用
- javascript - Javascript 正则表达式只允许最多 10 位的数字,不允许使用字符串和特殊字符
- node.js - 无法在 expo-react-native 应用程序上运行“expo start”,权限问题
- delphi - 如何在 paslibvlc 视频播放器中禁用活动音轨