Правильная инициализация ViewModel с использованием аргументов между фрагментами - PullRequest
0 голосов
/ 24 апреля 2020

Этот пример показывает использование ViewModel и как создать ViewModelFactory для инициализации ViewModel, передавая один аргумент. В конце примера есть примечание:

Note: In this app, it's not necessary to add a ViewModelFactory for the ScoreViewModel, because you can assign the score directly to the viewModel.score variable. But sometimes you need the data right when the viewModel is initialized.

Фактически, чтобы заполнить окончательный счет ScoreFragment, он говорит сделать следующее

binding.scoreText.text = viewModel.score.toString()

но разве это не так? Не следует ли присваивать binding.scoreText.text с viewModel.score.value.toString()? И как можно избежать использования ViewModelFactory для правильной инициализации переменной finalScore внутри ScoreFragmentViewModel, используя аргумент, предоставленный GameFragment, когда игра заканчивается? Так как ScoreFragment показывает только окончательный счет без каких-либо изменений, почему в последнем примере кода был добавлен наблюдатель в onCreateView из ScoreFragment?

    // Add observer for score
    viewModel.score.observe(viewLifecycleOwner, Observer { newScore ->
        binding.scoreText.text = newScore.toString()
    })

У меня также есть еще один простой вопрос. Предполагая, что у меня есть два фрагмента, первый просто показывает пару TextViews, а второй предназначен для их редактирования, так что второй фрагмент является единственным, способным модифицировать базовую модель, необходимо ли создавать две модели ViewModel? Второй фрагмент должен быть инициализирован с помощью TextViews вызывающего фрагмента, реализует ли ViewModelFactory для строго обязательной инициализации этих полей или существует более простой механизм для их инициализации?

1 Ответ

0 голосов
/ 25 апреля 2020

Пример, который вы упомянули, конечно, довольно образовательный и, возможно, он не похож на реальные проекты. Я постараюсь высказать свои мысли относительно ваших вопросов:

  1. ScoreViewModel в примере содержит только одно значение, и оно действительно никогда не меняется. Поэтому нет необходимости наблюдать за его изменениями, поэтому это значение не является LiveData и нет необходимости использовать

    viewModel.score.value.toString()

  2. Вы можете пропустить ViewModelFactory, если Ваш ViewModel не имеет параметров в конструкторе. Таким образом, вы можете создать свою ScoreViewModel без параметров, но использовать какой-либо тип установки publi c для поля «оценка» (и установить его из ScoreFragment с окончательной оценкой из комплекта). Это может быть не рекомендуется в некоторых случаях. Я думаю, что они написали эту заметку, чтобы подчеркнуть другой сценарий ios, который вы можете использовать для инициализации ViewModel. Возможно, это был не очень элегантный способ :-)

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

    viewModel.score.observe(viewLifecycleOwner, Observer { newScore -> binding.scoreText.text = newScore.toString() })

  4. Что касается двух фрагментов, ваш вопрос неясен. Если вы хотите, чтобы они совместно использовали некоторый объем данных (те же данные), вы можете использовать shared ViewModel . Например, эта общая ViewModel может содержать две строки LiveData, тогда первый фрагмент может просто «показать» эти строки (независимо от TextViews), а второй фрагмент может «редактировать» их

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...