12

PlayerオブジェクトのリストであるPlayersプロパティを持つTeamを含むViewModelがあります。TeamView内では、チームは深くロードされているため、プレーヤーデータはすでにメモリにあります。

選択した特定のPlayerクラスインスタンスをPlayerViewに渡すための最良の方法は何ですか?

問題は、MVVMCrossViewModelコンストラクターが現在のバージョンの文字列プロパティのみを含むことができることです。

私は次のアイデアを持っています:

  1. 選択したプレーヤーのIDを渡し、Team.PlayersプロパティをViewModelとしてPlayerViewに割り当てます。選択したプレーヤーがPlayerViewでフォーカスされたプレーヤーであり、PlayerViewが実際には「プレーヤー」ビューであり、ユーザーが他のチームプレーヤー間でもスワイプできる場合、これは合理的な解決策になります。

  2. ストレージのようなディクショナリで、ナビゲートアクション間でのみデータを伝送できるViewBagサービスのようなASP.Net MVCがあり、PlayerViewに渡されるパラメーターは、クラスインスタンスを指す特別なキーである「viewbag:PlayerId123」です。

  3. 選択したオブジェクトを文字列にシリアル化し、シリアル化されたオブジェクトとしてコンストラクターに渡します。それは可能ですが、私はこの解決策が好きではありません。

4

1 に答える 1

13

一般的なナビゲーションでは、MvvmCross は、ViewModel 間で文字列を渡すことのみを許可します。

これは、Xaml Uris や Android Intents などのメカニズムを介してプラットフォーム レベルでナビゲーションを行う必要があるためです。

あなたが提案する状況では、私が典型的に使用する一般的なパターンは次のとおりです。

  • 注入された ITeamService を使用して、TeamViewModel がネットワークからチーム データを取得すること
  • 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 内でチームに深い負荷がかかっているため、プレイヤーのデータは既にメモリ内にある」という仮定に問題があるためです。

問題は、Android や WP7 などのプラットフォームでは、オペレーティング システムが自由にアプリケーションをメモリから削除し、後で再起動できることです。これはWP7では tombstoning と呼ばれていますが、Android ではKilledと呼ばれているようです。

このような場合、後でユーザーが戻ったときに、オペレーティング システムがアプリケーションを再起動することがあります。この再起動は、ユーザーが最後にいたアクティビティに直接移動し、バックスタックを記憶します。その後、必要なオブジェクトをメモリに適切に復元するのはアプリケーション次第です。

これを説明する非常に小さな写真がいくつかあります...

Xamarin ドキュメントの Android ライフサイクル ここに画像の説明を入力

詳細については、XamarinMSDNを参照してください。


あなたのチーム/プレーヤーのケースでは、次の方法で水分補給に対処できる場合があります。

  • ITeamCache をファイルに基づくオブジェクトとして実装する - たとえば、メモリ内データの永続ストアとして JSON ファイルまたは SQLite データベースを使用できます。
  • 必要に応じてネットワークからデータを再フェッチするロジックをコードに実装する
  • これらのケースでは、いくつかの緊急ナビゲーション バックホーム戦略を実装します。これらのケースは、最新のリソースが豊富な電話の多くのアプリケーションではあまり発生しないためです。
  • ただクラッシュする - これはお勧めできませんが...

多くのアプリケーションが廃棄処理をうまく処理できないことは当然のことです...


注 - 小さなオブジェクトの場合、オプション 3 (シリアル化) はうまく機能しますが、アプリのリハイドレーションが発生し、ユーザーが PlayerViewModel から TeamViewModel に戻る状況では役に立ちません。


MvvmCross 内の Android ライフサイクルに関する最近の変更の詳細については、http: //slodge.blogspot.co.uk/2012/05/android-application-initialization-and.html を参照してください。

于 2012-05-18T20:39:16.477 に答える