Правильный способ обновления живых данных из модели?

#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
   }
}
 

Следующая картинка должна объяснить вам, как все выглядит

введите описание изображения здесь

Для получения более подробной информации проверьте это:

https://developer.android.com/jetpack/guide

viewmodels-and-livedata-patterns-antipatterns