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
我是 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