Android ViewModel отвечает только за хранение данных или за хранение данных + контроллер для просмотра? - PullRequest
3 голосов
/ 30 мая 2020

От официального мы знаем

Класс ViewModel разработан для хранения данных, связанных с пользовательским интерфейсом, и управления ими с учетом жизненного цикла

Но Я думаю, что многие разработчики используют ViewModel как хранилище данных и как контроллер (например, вызывающий репозиторий, сетевой клиент для данных). Я также использую как хранилище данных, так и контроллер для просмотра.

Android официальный пример кода также имеет лог c контроллера. От официальный :

class MyViewModel : ViewModel() {
  private val users: MutableLiveData<List<User>> by lazy {
     MutableLiveData().also {
        loadUsers()
     }
  }

  fun getUsers(): LiveData<List<User>> {
    return users
  }

  private fun loadUsers() {
    // Do an asynchronous operation to fetch users.
  }
}

Здесь loadUsers может вызвать Репозиторий или NetworkClient . Итак, здесь он действует как контроллер.

Я уверен, что многие разработчики поступают именно так, но, согласно определению, ViewModel должен хранить и управлять данными, связанными с пользовательским интерфейсом, должен ли ViewModel действовать как Контроллер ?

Я нашел поток переполнения стека this и this об этом.

Первый принятый ответ предлагал не использовать ViewModel как Контроллер и использовать Контроллер для других задач.

В разделе комментариев Второго @commonsware также предлагал не использовать сложные вещи, кроме данных.

Итак, мой вопрос:

  1. Какая будет фактическая ответственность ViewModel со стороны архитектурной концепции?
  2. Если мне нужно выполнить вызовы некоторых методов, связанных с View [например, запрос данных, сетевой вызов и другие вещи, связанные с бизнес-входом] где мне это сделать?
  3. и если мне нужно использовать контроллер , то как я подключаюсь View и Контроллер для вращения устройства и совместного использования контроллера между фрагментами?

Надеюсь, мой вопрос понятен всем

Заранее спасибо.

1 Ответ

1 голос
/ 30 мая 2020

Здесь loadUsers() может вызывать какой-то Repository или NetworkClient. Итак, здесь он действует как контроллер.

Я уверен, что многие разработчики поступают таким образом, но, согласно определению, ViewModel должен хранить и управлять данными, связанными с пользовательским интерфейсом, должна ли ViewModel действовать как контроллер?

Теоретически получение данных должно быть внутренним по отношению к LiveData, инициироваться наличием active observers и на основании этого принимать решение, что делать (в onActive()). Если LiveData на самом деле MediatorLiveData, то это также относится к любому блоку, связанному с addSource, поскольку блок, добавленный с addSource из MediatorLiveData, вызывается только тогда, когда MediatorLiveData наблюдает за активным наблюдателем

Вы можете увидеть, как эта техника используется в полной мере в и NetworkBoundResource. ViewModel хранит только данные и ничего не знает о загрузке данных.

Какая будет фактическая ответственность ViewModel с точки зрения архитектурной концепции?

Если вы видите комментарии Yi git Boyar (создатель ViewModel):

Я парень (или часть команды), который его добавил, и ему нечего было делать с MVVM. Все дело в том, чтобы дать людям класс, в который они должны помещать данные.

AA C не является реализацией MVVM, и концепция виртуальной машины не существует только как часть MVVM.

Фактически, основной мотивацией для этого было; мы говорили разработчикам, чтобы они не управляли данными в контроллере пользовательского интерфейса, и ответы были также, так где? И ViewModel стал тем ответом.

Мы хотим, чтобы она была моделью для вашего уровня представления (фрагмент, действие, что угодно). Оглядываясь назад, можно сказать, что было бы лучше выбрать новое имя, но назвать его действительно сложно.

В заключение: ViewModel - это Модель в сценарии MVC, где C - это действие или фрагмент, V - это расширенное представление, а M - это ViewModel.

Если мне нужно выполнить некоторые вызовы методов, связанных с View [например, запрос данных, сетевой вызов и другие вещи, связанные с бизнес-входом], где мне это сделать?

ViewModel получает данные в виде a LiveData, и LiveData "активируется" путем наблюдения за ними из представления с заданным жизненным циклом.

Сетевые вызовы также должны запускаться таким же образом (если вы следуете подходу, соответствующему разработкам LiveData ).

Теоретически, если у вас есть вызов входа в систему, вы также можете сделать это в контроллере, а не в модели, поэтому вы можете сделать это во фрагменте, даже если там такие уловки, как привязка данных Jetpack, которые позволят вам методы вызова из представления модели непосредственно из XML.

, и если мне нужно использовать контроллер, то как я подключаю View и Controller для вращения устройства и совместного использования контроллера между фрагментом?

ViewModel предоставляет LiveData и потенциально может также раскрывать LiveEvent, если вы напишете для этого необходимый код (к сожалению, это не предоставляется командой Jetpack , и ни то, ни другое не является привязкой команд ), и либо View, либо Controller могут при необходимости вызывать методы непосредственно на нем. ViewModel сохраняется при изменении конфигурации (не при смерти процесса, c), поэтому она не должна содержать прямую ссылку на представление.

...