2012-05-18 21 views
11

我有一個ViewModel,其中包含一個具有Player屬性的Team,它是Player對象的列表。在TeamView中,團隊深度加載,所以玩家數據已經在內存中。在MVVMCross中將對象傳遞給「導航到」viewmodel的最佳方式是什麼?

將給定的所選Player類實例傳遞給PlayerView的最佳方式是什麼?

問題是,MVVMCross ViewModel構造函數只能包含當前版本中的字符串屬性。

我有以下觀點:

  1. 傳遞選定玩家的ID和Team.Players屬性分配作爲視圖模型的PlayerView。如果所選擇的玩家只是PlayerView中的焦點玩家,並且PlayerView實際上是「玩家」視圖,則用戶可以在其他玩家之間滑動,這可能是一個合理的解決方案。

  2. 有一個像ViewBag服務的ASP.Net MVC,它只能在導航動作之間傳輸數據,存儲在字典中,傳遞給PlayerView的參數是一個「viewbag:PlayerId123」,它是一個指向類實例。

  3. 將所選對象序列化爲字符串,並將其作爲序列化對象傳遞給構造函數。這是可能的,但我不喜歡這個解決方案。

回答

13

在一般導航中,MvvmCross只允許在ViewModels之間傳遞字符串。

原因是導航需要通過Xaml Uris或Android Intents等機制在平臺級完成。

對於你的建議的情況下,一般模式我會typcially使用方法是:

  • 的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; } 
} 

注意到代碼以上測試是否玩家是null。這是因爲您的假設存在問題「在TeamView中,團隊深度加載,因此玩家數據已經存儲在內存中。」

問題是,在像Android和WP7這樣的平臺中,操作系統可以自由地將應用程序從內存中移除,然後再重新啓動。這在WP7上被稱爲Tombstoning,但似乎在Android上被稱爲Killed

在這些情況下,操作系統可能會在用戶導航回來後重新啓動應用程序。此重新啓動將直接發送到用戶最後一次的活動,並且它會記住後退堆棧 - 然後由您的應用程序將所有需要的對象重新充滿回到內存中。

這裏有一些很小的圖片解釋這個...

Android lifecycle from Xamarin docsenter image description here

有關更多詳細信息,請參閱XamarinMSDN


爲您的球隊/球員的情況下,你可能會能夠通過以下方式應對補液:

  • 將ITeamCache實現爲文件支持的對象 - 例如它可以使用JSON文件或SQLite數據庫作爲持久性存儲在內存中的數據
  • 實現代碼中的一些邏輯需要從網絡重新提取數據時
  • 實施一些緊急導航的揹回家戰略在這些情況下 - 因爲這些情況在現代資源豐富的電話的許多應用中不經常發生。
  • 就崩潰 - 儘管這是不可取的......

這並不奇怪,許多應用程序不處理立碑很好...


注 - 小物件,你的選項3(序列化)可以很好地工作 - 但是,這不會幫助你發生應用程序再水合,然後用戶從PlayerViewModel返回到TeamViewModel。


更多關於一些最近關於內MvvmCross Android的生命週期的變化,看到http://slodge.blogspot.co.uk/2012/05/android-application-initialization-and.html

+1

感謝您的回答斯圖爾特這是有道理的,我們很幸運,我們已經有一個客戶端SQLite數據庫,所以應用程序重新啓動是不言而喻的,只有ITeamCache應該支持它。我很高興地接受它作爲答案:-) –

+1

像大會樣本應該告訴你我通常做的事情https://github.com/slodge/MvvmCrossConference – Stuart

+0

如此豐富的解釋!謝謝。 – Askolein

相關問題