Каков наилучший способ передачи объектов в view-модель «переход к» в MVVMCross?

У меня есть ViewModel, которая содержит команду, у которой есть свойство Players, представляющее собой список объектов Player. В TeamView команда глубоко загружена, поэтому данные игрока уже находятся в памяти.

Каков наилучший способ передать данный выбранный экземпляр класса Player в PlayerView?

Проблема в том, что конструкторы MVVMCross ViewModel могут содержать только строковые свойства в текущей версии.

У меня есть следующие идеи:

Передайте идентификатор выбранного проигрывателя и назначьте свойство Team.Players в качестве ViewModel для PlayerView. Это может быть разумным решением, если выбранный игрок является просто сфокусированным игроком в PlayerView, а PlayerView действительно является представлением «игроков», где пользователь также может проводить пальцем между другими игроками команды.

Имеют ASP.Net MVC, подобный сервису ViewBag, который может переносить данные только между действиями навигации, в Словаре, подобном хранилищу, и параметр, передаваемый в PlayerView, представляет собой «viewbag: PlayerId123», который является специальным ключом, указывающим на экземпляр класса.

Serialize выбранного объекта в строку и передать его как сериализованный объект в конструктор. Это возможно, но мне не нравится это решение.

Ответы на вопрос(1)

Решение Вопроса

ViewModels.

Причина этого заключается в том, что навигация должна осуществляться на уровне платформы с помощью таких механизмов, как Xaml Uris или Android Intents.

Для ситуации, которую вы предлагаете, я бы обычно использовал следующую схему:

что TeamViewModel получает данные команды из сети с помощью встроенного ITeamService что TeamViewModel также использует внедренный одноэлементный ITeamCache для кэширования Team то, что навигация происходит с помощью вызова как:

this.RequestNavigate<PlayerViewModel>(new { teamId, playerId })

PlayerViewModel затем получает TeamId и PlayerId в своем конструкторе и использует ITeamCache для сбора нужного игрока

Этот код может выглядеть так:

 public class TeamViewModel 
     : MvxViewModel
     , IMvxServiceConsumer<ITeamCache>
 {
     public TeamViewModel(string teamId, string playerId)
     {
         var teamCache = this.GetService<ITeamCache>();
         Player = teamCache.GetPlayer(teamId, playerId);
         if (Player == null)
         {
             // todo - handle this error somehow!
         }
     }

     public Player Player { get; set; }
 }

Обратите внимание, что приведенный выше код проверяет, является ли Playernull. Это связано с тем, что вы предполагаете, что «в TeamView команда глубоко загружена, поэтому данные игрока уже находятся в памяти».

Проблема в том, что на таких платформах, как Android и WP7, операционная система может свободно удалять ваше приложение из памяти и затем перезагружать его позже. Это называется Tombstoning на WP7, но, кажется, называется Убитый на Android.

В этих случаях операционная система может перезапустить приложение позже, когда пользователь перейдет обратно. Этот перезапуск приведет к выполнению действия, в котором последний раз находился пользователь, и он запомнит задний стек - тогда ваше приложение будет должным образом перенаправить все необходимые объекты обратно в память.

Вот несколько маленьких картинок, объясняющих это ...

Подробнее см. Xamarin а также MSDN

В случае вашей команды / игрока вы можете справиться с регидратацией:

Реализация ITeamCache как объекта с файловой поддержкой - например, он может использовать файл JSON или базу данных SQLite в качестве постоянного хранилища данных в памяти Внедрение в ваш код некоторой логики, которая при необходимости обновляет данные из сети В этих случаях реализуется некоторая стратегия экстренной навигации-возврата-домой, поскольку такие случаи не часто встречаются во многих приложениях на современных телефонах с богатым ресурсом. Просто сбой - хотя это не рекомендуется ...

Не удивительно, что многие приложения не очень хорошо справляются с надгробиями ...

Примечание - для небольших объектов ваш вариант 3 (сериализация) может работать хорошо, однако это не поможет вам в ситуации, когда происходит регидратация приложения, а затем пользователь возвращается назад от PlayerViewModel к TeamViewModel.

Подробнее о последних изменениях в стиле жизни Android в MvvmCross см. Вhttp: //slodge.blogspot.co.uk/2012/05/android-application-initialization-and.htm

 Attila Hajdrik18 мая 2012 г., 22:50
Спасибо за ответ, Стюарт, это имеет смысл, нам повезло, что у нас уже есть база данных SQLite на стороне клиента, поэтому перезапуск приложения не составляет никакого труда, только ITeamCache должен его поддерживать. Я с радостью принимаю это как ответ: -)
 Stuart18 мая 2012 г., 22:54
Что-то вроде образца конференции должно показать вам то, что я обычно делаю Github.com / slodge / MvvmCrossConference
 Askolein10 янв. 2013 г., 22:59
Такое богатое объяснение! Благодарность
 Stuart10 янв. 2013 г., 23:44
Теперь есть обновление параметров, разрешенных в последнем vnext-коде - см. Slodge.blogspot.co.uk / 2013/01 / ...

Ваш ответ на вопрос