在MVVMCross中将对象传递给"导航到"viewmodel的最佳方法是什么?

Att*_*rik 12 c# xamarin.ios windows-phone-7 xamarin.android mvvmcross

我有一个ViewModel,它包含一个Team,它有一个Players属性,它是一个Player对象列表.在TeamView中,Team是深度加载的,因此播放器数据已经在内存中.

将给定的选定Player类实例传递给PlayerView的最佳方法是什么?

问题是MVVMCross ViewModel构造函数只能包含当前版本的字符串属性.

我有以下想法:

  1. 传递所选Player的Id并将Team.Players属性作为ViewModel分配给PlayerView.如果所选择的玩家只是PlayerView中的焦点玩家并且PlayerView实际上是"玩家"视图,那么这可以是合理的解决方案,其中用户也可以在其他团队玩家之间滑动.

  2. 有一个像ViewBag服务这样的ASP.Net MVC只能在导航动作之间传递数据,在类似存储的字典中,传递给PlayerView的参数是一个"viewbag:PlayerId123",它是一个指向类实例的特殊键.

  3. 将所选对象序列化为字符串,并将其作为序列化对象传递给构造函数.这是可能的,但我不喜欢这个解决方案.

Stu*_*art 13

在一般导航中,MvvmCross只允许在ViewModel之间传递字符串.

原因是导航需要通过Xaml Uris或Android Intents等机制在平台级别完成.

对于你建议的情况,我将典型使用的一般模式是:

  • TeamViewModel使用注入的ITeamService从网络获取团队数据
  • TeamViewModel还使用注入的单例ITeamCache来缓存团队
  • 导航通过如下调用发生:

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; }
 }
Run Code Online (Sandbox Code Playgroud)

请注意,上面的代码测试Player是否为null.这是因为您的假设存在问题"在TeamView中,Team是深度加载的,因此播放器数据已经在内存中."

问题是在Android和WP7等平台上,操作系统可以自由地从内存中删除你的应用程序,然后再重新启动它.这在WP7上被称为Tombstoning,但似乎在Android上被称为Killed.

在这些情况下,操作系统可能会在用户导航回来后重新启动您的应用程序.这种重新启动将直接进入用户最后的活动,它将记住后备堆栈 - 然后由您的应用程序将所有需要的对象正确地重新水化回内存.

这里有一些非常小的图片来解释这个......

来自Xamarin docs的Android生命周期 在此输入图像描述

有关更多详细信息,请参阅XamarinMSDN


对于您的团队/玩家案例,您可以通过以下方式应对补液:

  • 将ITeamCache实现为文件支持的对象 - 例如,它可以使用JSON文件或SQLite数据库作为内存数据的持久存储
  • 在代码中实现一些逻辑,在需要时从网络中重新获取数据
  • 在这些情况下实施一些紧急导航回家策略 - 因为这些情况在现代资源丰富的手机上的许多应用中并不常见.
  • 只是崩溃 - 虽然这是不可取的......

毫不奇怪,许多应用程序都不能很好地处理墓碑...


注意 - 对于小对象,您的选项3(序列化)可以很好地工作 - 但是,这对于发生应用程序补液并且用户然后从PlayerViewModel导航回TeamViewModel的情况无效.


有关MvvmCross中Android lifecyle的最新更改的更多信息,请参阅http://slodge.blogspot.co.uk/2012/05/android-application-initialization-and.html