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

时间:2012-05-18 19:55:16

标签: c# windows-phone-7 xamarin.ios xamarin.android mvvmcross

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

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

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

我有以下想法:

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

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

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

1 个答案:

答案 0 :(得分:13)

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

原因是导航需要通过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; }
 }

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

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

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

以下是一些非常小的图片来解释这个...

Android lifecycle from Xamarin docs enter image description here

有关详细信息,请参阅XamarinMSDN


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

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

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


注意 - 对于小对象,您的选项3(序列化)可以正常运行 - 但是,这对于发生应用程序补液并且用户然后从PlayerViewModel导航回TeamViewModel的情况无法帮助您。


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