#android #mvvm #android-livedata
#Android #mvvm #android-livedata
Вопрос:
«Правильный» способ обновления представлений с помощью Android — это LiveData. Но я не могу определить «правильный» способ подключения этого к модели. Большая часть документации, которую я видел, показывает подключение к Room, которое возвращает объект LiveData. Но (предполагая, что я не использую Room), возврат объекта LiveData (который «осознает жизненный цикл», поэтому специфичен для платформы activity / view Android) в моей модели, как мне кажется, нарушает разделение проблем?
Вот пример с активностью…
class MainActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_activity);
val viewModel = ViewModelProvider(this).get(UserViewModel::class.java)
val nameText = findViewById<TextView>(R.id.nameTextBox)
viewModel.getName().observe(this, { name ->
nameText.value = name
})
}
}
И ViewModel…
class UserViewModel(): ViewModel() {
private val name: MutableLiveData<String> = MutableLiveData()
fun getName() : LiveData<String> {
return name
}
}
Но как мне затем подключить это к моей модели, не помещая в мою модель объект, учитывающий жизненный цикл, который предназначен для конкретной среды (LiveData)…
class UserModel {
val uid
var name
fun queryUserInfo() {
/* API query here ... */
val request = JSONObjectRequest( ...
{ response ->
if( response.name != this.name ) {
this.name = response.name
/* Trigger LiveData update here somehow??? */
}
}
)
}
}
Я думаю, что, возможно, смогу поместить наблюдаемый объект в свою модель, а затем использовать его для запуска обновления LiveData в моей ViewModel. Но не находите никаких мест, где кто-либо еще говорит, что это «правильный» способ сделать это. Или я могу создать экземпляр объекта LiveData в ViewModel из наблюдаемого объекта в моей модели?
Или я просто думаю об этом неправильно или я что-то упускаю?
Комментарии:
1. Взгляните на все изображения на следующей странице, и вам должно быть намного проще понять viewmodels-and-livedata-patterns-antipatterns
2. Итак, похоже, что ваш ответ заключается в том, чтобы включить LiveData в модель? То, что наличие компонента «с учетом жизненного цикла» (который принимает объект LifecycleOwner), объявленного в модели, на самом деле не нарушает философию «разделения задач»?
3. Нет, держите модель в чистоте. Создайте репозиторий для загрузки данных (из api или room) и просматривайте LiveData (из репозитория) в ViewModel… Проверьте ответ ниже…
Ответ №1:
Это из официальной документации. Проверьте комментарии в коде…
Пользовательская модель должна оставаться чистой
class UserModel {
private val name: String,
private val lastName: String
}
Создать репозиторий для сбора данных из сети
class UserRepository {
private val webservice: Webservice = TODO()
fun getUser(userId: String): LiveData<UserModel > {
val data = MutableLiveData<UserModel>() //Livedata that you observe
//you can get the data from api as you want, but it is important that you
//update the LiveDate that you will observe from the ViewModel
//and the same principle is in the relation ViewModel <=> Fragment
webservice.getUser(userId).enqueue(object : Callback<UserModel > {
override fun onResponse(call: Call<User>, response: Response<UserModel >) {
data.value = response.body()
}
// Error case is left out for brevity.
override fun onFailure(call: Call<UserModel >, t: Throwable) {
TODO()
}
})
return data //you will observe this from ViewModel
}
}
Следующая картинка должна объяснить вам, как все выглядит
Для получения более подробной информации проверьте это: