我有一个ViewModel,其中包含一个具有Players属性的Team,该属性是Player对象的列表。在TeamView中,Team是深度加载的,因此播放器数据已经在内存中。
将给定的选定Player类实例传递给PlayerView的最佳方法是什么?
问题是MVVMCross ViewModel构造函数只能包含当前版本的字符串属性。
我有以下想法:
传递所选播放器的ID并将Team.Players属性作为ViewModel分配给PlayerView。如果所选择的玩家只是PlayerView中的焦点玩家并且PlayerView实际上是“玩家”视图,那么这可以是合理的解决方案,其中用户也可以在其他团队玩家之间滑动。
有一个像ViewBag一样的ASP.Net MVC服务,它只能在导航动作之间传递数据,在类似存储的字典中传递数据,传递给PlayerView的参数是一个“viewbag:PlayerId123”,这是一个指向的特殊键类实例。
将所选对象序列化为字符串,并将其作为序列化对象传递给构造函数。这是可能的,但我不喜欢这个解决方案。
答案 0 :(得分:13)
在一般导航中,MvvmCross只允许在ViewModels之间传递字符串。
原因是导航需要通过Xaml Uris或Android Intents等机制在平台级别完成。
对于你建议的情况,我将典型使用的一般模式是:
this.RequestNavigate<PlayerViewModel>(new { teamId, playerId })
此代码可能如下所示:
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。
在这些情况下,操作系统可能会在用户导航回来后重新启动您的应用程序。这种重新启动将直接进入用户最后的活动,并且它将记住后备堆栈 - 然后由您的应用程序完成将任何所需对象重新水化回内存。
以下是一些非常小的图片来解释这个...
对于您的团队/运动员案例,您可以通过以下方式应对补液:
毫不奇怪,许多应用程序都不能很好地处理墓碑......
注意 - 对于小对象,您的选项3(序列化)可以正常运行 - 但是,这对于发生应用程序补液并且用户然后从PlayerViewModel导航回TeamViewModel的情况无法帮助您。
有关MvvmCross中Android lifecyle的最新更改的更多信息,请参阅http://slodge.blogspot.co.uk/2012/05/android-application-initialization-and.html