
В MVVM всякий раз, когда вы хотите показать тосты или закусочную или отправить намерение, вы должны отправить сообщение из модели ViewModel в действие или фрагмент и попросить его выполнить задание, но обычные методы для этого имеют большие резервы. .
В примере ShowToast ViewModel решает, когда показывать сообщение и какое сообщение показывать, но именно представление отвечает за отображение фактического сообщения. Я подробно описал обязанности View-ViewModel в другой статье. MVVM - Как View и ViewModel должны взаимодействовать?
Неправильные способы обработки событий
Использование интерфейса, функции высшего порядка или любых других обратных вызовов
Мы можем определить интерфейс в ViewModel и позволить Activity / Fragment реализовать его, а затем всякий раз, когда происходят какие-то события, мы просто вызываем метод интерфейса. Это просто, понятно и работает, но это самый глупый выбор. Почему? потому что, в отличие от MVP, в MVVM мы не используем интерфейсы для связи с View, а ViewModel не должен иметь никаких ссылок на View. Нарушение MVVM недопустимо!
Отправка событий с помощью LiveData
Мы можем поместить данные о наших событиях в LiveData и позволить Activity / Fragment наблюдать за ними. Это работает, но у него есть и недостатки. Что-то вроде ниже
Но это не сработает, потому что:
- Потому что в случае уничтожения активности / фрагмента, а ViewModel - нет. n изменение конфигурации, например, view будет снова уведомлен о событии, и мы можем обработать событие более одного раза. Если мы увидим данные после
onViewCreated, это даже стоит того, поскольку теперь каждый раз, когда представление будет уничтоженоonDestroryViewи воссоздано, мы будем получать уведомление снова. - Если несколько фрагментов используют одну и ту же ViewModel, все они получают уведомление о событии и обрабатывают его одновременно, а это может быть не тем, что нам нужно. Обычно нам нужен один конкретный наблюдатель для обработки события.
Отправка событий с OneTime Only LiveData
Существует некоторая реализация LiveData, которая уведомляет наблюдателей только один раз, поэтому мы не получаем первую проблему с предыдущим решением.
Это гораздо лучшее решение, и я знаю людей, которые какое-то время используют его в производстве, но мне оно все еще не нравится, потому что оно не решает вторую проблему с предыдущим решением, и оно того стоит! Если у нас есть несколько фрагментов, наблюдающих те же данные, теперь только один из них получает данные, и мы не знаем, какой именно!
Правильный способ обработки событий!
Мы можем использовать LiveData и получить от него все преимущества, в основном тот факт, что он осведомлен о жизненном цикле, и он будет уведомлять представление только тогда, когда оно находится в активном состоянии, но не получит никаких предыдущих недостатков, используя настраиваемую оболочку вокруг нашего данные. Наше решение было бы таким
Теперь отличается то, что мы делаем обработку событий явно, все наблюдатели получают данные, и они могут получить более одного раза (так как действие / фрагмент может быть уничтожен и после реакции получить данные снова), но событие будет обработано только один раз. но первый наблюдатель, который решит разобраться с этим.
Последний мир
В моей статье MVVM - как должны взаимодействовать View и ViewModel? вы видите, что обработка некоторых событий, таких как показ тоста, должна выполняться внутри представления, но подготовка данных для показа таких сообщений, как сообщение ведьмы, является обязанностью ViewModel, поэтому нам нужен способ отправить эти данные в представление, и то, что я правильно описал, это лучшее, что я нашел до сих пор! (Это не мои оригинальные решения, но я не помню, где впервые прочитал его, чтобы указать на автора).
Кроме того, дайте мне знать, что вы думаете, в разделе комментариев ниже, Подписывайтесь на МЕНЯ, если вам интересно прочитать и другие мои истории.