5

ViewModel がキャッシュからリロードされているときに、フレームワークをインターセプトして再初期化を実行できるようにする必要があります。ViewModel は再作成されていないため、Init()、MvxViewModel.InitFromBundle、MvxViewModel.ReloadFromBundle のいずれのメソッドも使用できません。

戻るボタンをクリックすると、一貫性のない状態の ViewModel が復元される状況をデバッグしようとしています。ある種の MvxViewModel.OnReloading() が役立ちます。

v3でこれを行う方法はありますか?

編集:

SecondPageViewModel に移動するコマンドを公開する FirstPageViewModel があるとします。私が観察していることに基づいて、SecondPageView でシミュレーターの戻るボタンをクリックすると、FirstPageViewModel は構築されません。代わりに、何らかのキャッシュから取得され、ビューにバインドされていると思います。このキャッシュは、IMvxSingleViewModel キャッシュの実装である可能性があります。

したがって、ViewModel 構築後の通常のフロー (Init()、InitFromBundle()、および ReloadFromBundle() を呼び出す) は、このシナリオには適用されません。つまり、ViewModel が新しく構築されたばかりか、キャッシュから復活したかに関係なく、ViewModel を再初期化する方法が必要です。前者の場合は、Init() メソッドを使用できます。後者の場合、ViewModel 自体でこれを行う方法はありません。

これが問題です:

FirstViewModel から SecondViewModel に渡される ICollectionService のインスタンスがあります。FirstView には、この CollectionService にバインドされた ListView も含まれています。CollectionService は厳密に型指定されていないため、これを渡し、適切な項目テンプレートを使用してその項目をビューに表示できます。

SecondViewModel を表示する前に、FirstViewModel はいくつかのリモート データを取得し、CollectionService に入力します。SecondViewModel が表示されると、そのビューは別のアイテム テンプレートを使用して CollectionService からのデータを表示します。ただし、戻ると、FirstViewModel がまだ CollectionService を参照しているため、FirstViewModel が再初期化されない限り、FirstView は SecondViewModel によって使用されたデータをレンダリングし、その過程で CollectionService をクリアします。アプローチが間違っているかもしれませんが、これが私の問題の核心です。

この再初期化が Core モジュールで発生するため、Windows Phone と iOS で同じ動作が予想されるため、プラットフォームが違いを生むかどうかはわかりません。それにもかかわらず、これらは Android での観察です。

ティア。

4

2 に答える 2

6

より多くの情報を提供するために質問を更新していただきありがとうございます。

クロスプラットフォーム開発に MvvmCross アプローチを使用すると、ネイティブ UI プラットフォームを活用できます。これは、開発者がこれらのプラットフォームについて少し学ぶ必要があることを意味します。理解すべき重要なことの 1 つは、ナビゲーション スタックで使用される場合を含め、「ビュー」のライフサイクルです。

デフォルトでは、MvvmCross はビュー モデルを長時間キャッシュしません。画面の遷移 (回転など) 中に発生する一時的なキャッシュがときどきありますが、期間キャッシュはなくなりました。代わりに、新しいビューが作成されると、mvx はデフォルトでそれに対応する新しいビューモデルを作成し、そのペアは「生涯」一緒に残り、寿命はビューによって決定されます。

各プラットフォームの基本的なライフサイクルとナビゲーション パラダイムについて、少し時間をとって読むことをお勧めします。

  • iOS では、これは特に、UiViewControllers のスタックをメモリ内に維持する UiNavigationController について学ぶことを意味します (それぞれが mvx で個々のビューモデルと結合されます)。

  • RootFrame が RAM にページのスタックを保持している WindowsPhone でも状況は似ています。ここには厄介な問題があります - トゥームストーン - しかし、基本的なライフサイクルを理解するまで忘れてください。

  • Android でも状況は似ていますが、少し異なります。基本的なアプリの場合、Android はアプリの存続期間中、アクティビティ ページのスタックを RAM に保持すると想定できます。ただし、Android は実際にはそれよりもはるかに複雑です。OS は、メモリを再利用することを決定したときに、RAM からバックスタック項目を削除できます。このような場合、時々心配すべき「墓石」と脱水症状がありますが、繰り返しますが、基本を理解するまでは無視することをお勧めします.

  • winrt では、デフォルトでは、状況は実際に説明で理解したとおりです。バックスタックは状態情報のみを保持します。ビュー自体は RAM にキャッシュされません。

上記のストーリーから、各プラットフォームのナビゲーション スタックでのビューのライフサイクルのアイデアが得られることを願っています。したがって、ビューモデルのライフサイクルも得られます。


ビューモデル (または他のアプリ レベル オブジェクト) にビューの可視性の状態を知らせたい場合は、各プラットフォームでいくつかのビュー イベントをインターセプトし、これらのイベントをビューに渡す必要があります。モデル。

たとえば、FirstViewModel は OnMadeVisible() をカスタム Api として公開できます。その場合、Windows では OnNavigatedTo、Android では OnResume、iOS では ViewDidAppear から呼び出されたことを確認できます。


または、ViewModel-ViewModel 通信の一般的なメカニズムを見ている場合は、次のようなものを見ることをお勧めします


ノート:

明らかに、ナビゲーション スタックだけがナビゲーション パラダイムではありません。アプリでフライアウト、タブ、分割ビュー、ハンバーガーなども使用している場合は、それらのビューのライフサイクルも理解する必要があります。

View のライフサイクルについて疑問がある場合は、そのコンストラクターと主要なライフサイクル イベントにトレースを追加することが最初のステップとして適切です。


最後に、デフォルトのビューモデルの場所とビューモデルのライフサイクルがアプリに必要なものではないと判断した場合 (たとえば、シングルトン ビューモデルを使用する場合)、これは簡単に実現できます。App.cs でビュー モデル ロケーターをオーバーライドすることを検討してください。クラス。

于 2013-07-25T20:06:56.697 に答える