【问题标题】:Sharing same MutableLiveData between Repository and ViewModel在 Repository 和 ViewModel 之间共享相同的 MutableLiveData
【发布时间】:2018-06-18 13:23:34
【问题描述】:

我正在研究架构组件/MVVM。

假设我有一个存储库、一个 ViewModel 和一个 Fragment。我使用Resource 类作为包装器来公开网络状态,就像Guide to architecture components 中所建议的那样。

我的存储库目前看起来像这样(为简洁起见进行了简化):

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 方法,以便 Repository 使用 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) {
    ...
}

【问题讨论】:

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


【解决方案1】:

感谢@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)。看起来合法吗?

【讨论】:

  • 似乎是一个很好的答案,但是您将如何解决延迟初始化的 livedata 对象的问题。例如:一旦你得到列表,你想获取另一种数据。如果没有在视图中观察它的方法,您如何使之成为可能?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 2019-07-02
  • 2010-11-12
  • 1970-01-01
相关资源
最近更新 更多