我有一个BaseViewModel,它的基本功能是获取用户数据,如下所示:
abstract class BaseViewModel(
private val repository: BaseRepository
) : ViewModel() {
private var _userResponse: MutableLiveData<Resource<UserResponse>> = MutableLiveData()
val userResponse: LiveData<Resource<UserResponse>> get() = _userResponse
fun getUserData() = viewModelScope.launch {
_userResponse.value = Resource.Loading
_userResponse.value = repository.getLoggedInUserData()
}
}在我的片段中,只需调用viewModel.getUserData()就可以访问这些数据。这个很管用。但是,我希望现在能够编辑数据。例如,UserResponse的数据类如下所示:
data class UserResponse(
var id: Int,
var username: String,
var email: String
)在其他片段中,我想编辑用户名和电子邮件。如何访问UserResponse对象并编辑它?这是做事情的好方法吗?应该在任何地方访问getUserData,这就是为什么我要将它包含在抽象的BaseViewModel中。每当UserResponse为null时,我执行以下检查:
if (viewModel.userResponse.value == null) {
viewModel.getUserData()
}发布于 2022-02-13 10:25:00
如果您希望能够编辑userResponse中的数据,那么您所谈论的实际上就是更改它所保存的值,对吗?这样做的最佳方法是通过ViewModel本身:
abstract class BaseViewModel(
private val repository: BaseRepository
) : ViewModel() {
private var _userResponse: MutableLiveData<Resource<UserResponse>> = MutableLiveData()
val userResponse: LiveData<Resource<UserResponse>> get() = _userResponse
fun setUserResponse(response: UserResponse) {
_userResponse.value = response
}
...
}这有几个优点--首先,视图模型负责数据的保存和管理,并提供一个读取、观察和更新数据的接口。而不是有很多地方的数据被操纵,这些地方只是调用这一个函数。如果您需要的话,这会使以后的更改变得容易得多--调用函数的代码可能根本不需要更改!
这也意味着您可以更容易地扩展更新逻辑,因为它都集中在VM中。需要将新的值写入SavedStateHandle,这样应用程序就不会丢失吗?只需将其放到更新函数中即可。或者把它保存到数据库里?把那个扔进去。没有人需要知道那里发生了什么
另一个优点是您实际上在LiveData上设置了一个新值,这意味着您的更新行为是一致的和可预测的。如果用户响应发生了变化(要么是一个全新的响应,要么是对当前响应的更改),那么所有observe LiveData都会看到更新,并且可以决定如何处理它。不像这样的想法那么脆弱,即当前响应的一个更改是“新的”,而另一个更改是“更新”,观察者只关心其中的一个,而不需要被通知另一个。更改处理方式的一致性将避免稍后引入bug,只会使人们更容易对所发生的事情进行推理
没有什么可以阻止您更新保存在userResponse中的对象的属性,就像没有什么可以阻止您在LiveData中保存一个List,并将元素添加到该列表中一样。所有引用该对象的内容都会看到新的数据,但前提是它们必须查看它。LiveData和观察者模式的目的是将更新推送给观察者,这样他们就可以对更改做出反应(比如,更新UI中显示的文本)。如果您更改了该数据类中的一个var,那么如何确保所有需要看到这些更改的东西都能看到它们呢?当应用程序被开发出来时,你怎么能确保这种情况总是发生,可能是由其他人开发的呢?观察者模式是为了简化逻辑更新的发生,通知观察者,结束。
如果您的打算这样做,那么我仍然建议在您的VM中添加一个更新函数,让它更新var。
fun setUserResponse(response: UserResponse) {
_userResponse.value?.run {
id = response.id
username = response.username
email = response.email
}
}如果您决定以后对所有更改采用完整的观察者模式,那么所有的东西都已经以正确的方式调用了该函数,不需要在那里进行更改。或者你可以做一些单独的updateEmail(email: String)等功能,不管你想做什么。但是把所有的逻辑都放在VM中是个好主意,这就是它的目的
哦,如果你想戳它的话,你可以通过userResponse.value访问这个对象,但是就像我说过的,最好在VM中的函数中这样做,将实现细节、空安全等保持在一个地方,这样调用者就不需要去处理它了。
发布于 2022-02-13 06:53:54
更新userResponse的理想方法--您应该更改/编辑_userResponse,以便您的userResponse --我们将提供更新的数据。
应该是这样的
_userResponse.value = Resource<UserResponse>()https://stackoverflow.com/questions/71098157
复制相似问题