首页 文章

在Repository和ViewModel之间共享相同的MutableLiveData

提问于
浏览
2

我正在围绕Architecture Components / MVVM进行整理 .

让's say I have a repository, a ViewModel and a Fragment. I' m使用 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创建一个新实例) .

我试图找出确保在Repository和ViewModel之间使用相同LiveData变量的最佳方法 .

我想过将LiveData从ViewModel传递给getLists方法,以便Repository将使用ViewModel中的对象,但即使它有效,这似乎也是错误的 .

我的意思是这样的:

ViewModel

var myLiveData = MutableLiveData<Resource<List<Something>>>()

fun getLists(organizationId: String, forceRefresh: Boolean = false) {
   myRepository.getLists(myLiveData, organizationId)
}

Repository

fun getLists(data: MutableLiveData<Resource<List<Something>>>, organizationId: String) {
    ...
}

1 回答

  • 2

    我想我知道如何做到这一点,感谢@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) . 似乎是合法的?

相关问题