MVVM 模式中的 LiveData 和改进的 kotlin

LiveData in MVVM pattern with retrofit kotlin

我是 MVVVM 和改造的新手,我已经成功实施了 MVVM,并且能够将数据从改造移动到存储库,然后将存储库移动到 ViewModel 和视图。

在执行此操作时,我遇到了一个巨大的困惑,如下所述。在第一种情况下,我的代码如下所示:

存储库:

 fun iniateOTPprocess() : LiveData<GenericResponse> {


    RetroUtils.getApiManager().listRepos().enqueue(object : RetrofitCallback() {

        override fun onResponse(call: Call<GenericResponse>, response: Response<GenericResponse>) {
            super.onResponse(call, response)

            result.value = response.body()

        }
    }

    )

  return result
}

视图模型:

 class LoginViewModel2(application: Application) : AndroidViewModel(application) {

lateinit var username: MutableLiveData<String>
lateinit var password: MutableLiveData<String>
var repository: LoginRepository = LoginRepository(application)
var data = MediatorLiveData<GenericResponse>()
var result = MutableLiveData<GenericResponse>()

init {
    data.addSource(result , Observer {
        data.postValue(it)
    })
}

fun onLoginBtnCLicked() {
    initiateOTP()
}

private fun initiateOTP() {
  result =  repository.iniateOTPprocess()
}

  fun getResponse() : MediatorLiveData<GenericResponse>{
   return data
  }
 }

Mediator 实时数据一旦更新就永远不会以这种方式更新。

但是如果我将此代码更改为

存储库

  class LoginRepository(var application: Application) {

var callback: RetrofitCallback = RetrofitCallback()
var result = MutableLiveData<GenericResponse>()

fun iniateOTPprocess() {

    RetroUtils.getApiManager().listRepos().enqueue(object : RetrofitCallback() {

        override fun onResponse(call: Call<GenericResponse>, response: Response<GenericResponse>) {
            super.onResponse(call, response)

            result.value = response.body()
        }
    }
    )
}

fun getData(): MutableLiveData<GenericResponse> {
    return result
}
}

视图模型

class LoginViewModel2(application: Application) : AndroidViewModel(application) {

lateinit var username: MutableLiveData<String>
lateinit var password: MutableLiveData<String>
var repository: LoginRepository = LoginRepository(application)
var data = MediatorLiveData<GenericResponse>()
var result = MutableLiveData<GenericResponse>()

init {
    data.addSource(repository.getData(), Observer {
        data.postValue(it)
    })
}

fun onLoginBtnCLicked() {
    initiateOTP()
}

private fun initiateOTP() {
    repository.iniateOTPprocess()
}

 fun getResponse() : MediatorLiveData<GenericResponse>{

   return data
 }
}

此代码神奇地开始工作。在视图中,我在两种情况下都观察了 getResponse() 方法。这里的任何人都可以帮助解决混乱并解释魔术发生的地方。提前致谢。

在您的第一个场景中,即使您正在通过此功能更新result

private fun initiateOTP() {
  result =  repository.iniateOTPprocess()
}

您将无法观察到这个新 result 实例中的变化,因为您已经在观察实例化 ViewModel 时创建的第一个 result 实例:

var result = MutableLiveData<GenericResponse>() // you are observing this instance
init {
    // this result never gets updated
    data.addSource(result , Observer {
        data.postValue(it)


    })

}

...

 fun getResponse() : MediatorLiveData<GenericResponse>{

    return data

 }

您的代码不遵循 MVVM 模式,每个实时数据都必须有观察者, 当您在 init{} 声明该值时,它还没有准备好,因为它是异步的。 如果您更改为:

data.addSource(repository.iniateOTPprocess(), Observer {
        data.postValue(it)
})

代码可以运行,这是学习 MVVM 和 livedata 模式的最佳来源 google codelabs