Модель перехода между пунктами назначения
Я работаю над приложением, которое использует Jetpack Compose с Jetpack Compose Navigation. В одном представлении (пункте назначения) я показываю список записей (назовем его представлением A с моделью A). Из этого представления пользователь может перейти к представлению создания (представление B с моделью B), где можно создать новую запись. После успешного создания я хочу обновить список в модели A, чтобы пользователю не нужно было обновлять представление A после возврата, чтобы увидеть вновь созданную запись.
Можно ли передавать класс ViewModel между пунктами назначения с помощью NavHost таким или любым другим способом?
1 ответ
Согласно руководству « Думая при написании»:
ваши компоненты отвечают за преобразование текущего состояния приложения в пользовательский интерфейс каждый раз, когда наблюдаемые данные обновляются.
Это состояние приложения является источником истины. Это соответствует Руководству по архитектуре приложения , где ваше состояние принадлежит компонентам более низкого уровня, которые отвечают за фактическую выборку, хранение и кэширование данных, которые затем отображаются на уровне пользовательского интерфейса. Этот уровень, отвечающий за выборку, хранение и кэширование данных, часто называют «уровнем репозитория».
Это означает, что прямая передача снимков данных между пунктами назначения в вашем навигационном графе - это совершенно неправильный способ решения проблемы: он создает проблему с источником истинности (доверяете ли вы снимку, который вы отправили между пунктами назначения или репозиторием?). Ответ всегда один: ваш репозиторий всегда должен быть источником истины, и вы никогда не должны передавать моментальные снимки данных между получателями. Таким образом, каждый экран , который использует хранилище в качестве источника истины автоматически имеет самую актуальную информацию и не существует и не необходимость «обновления» ваши данные.
Итак, ваша архитектура будет включать три уровня:
- Единый репозиторий, в котором хранится ваш список записей. Самой простой частью этого может быть просто список, хранящийся в памяти как
mutableStateOf<List<Entry>>()
которые вы обновляете при изменении данных с новым списком. Этот класс будет отвечать за взаимодействие с сервером, локальное кеширование и т. Д. - (необязательно и рекомендуется) слой ViewModels, один для экрана A и один для экрана B, которые предоставляют только наборы методов из репозитория, специально необходимые для этого экрана (т. е. ваша ViewModel A может открывать
getEntries()
, в то время как ViewModel B может открыватьcreateEntry(Entry)
метод. - Экран A и B сосредоточены исключительно на отображении данных, полученных из связанной с ними ViewModel. Поскольку оба взаимодействуют с одним и тем же уровнем репозитория, экран B, создающий запись, обновит список, из которого экран A будет извлекать свои данные.