4

MVVMアプローチは素晴らしく、十分に確立されています。ただし、シーンを想像してみてください。ユーザーが実行時間の長いタスクを開始できるアプリページがあります。ローカルデータベースとリモートデータベースの同期のように。このタスクは長くなる可能性があるため、適切に中断する必要があります。次に、ユーザーは詳細ページに移動してページを離れます。アプリはまだ実行中であるため、その長い非同期操作をキャンセルすることは意味がありません。しかし、突然ユーザーが電話を受けたため、アプリが非アクティブ化されました。

MVVMの私の(おそらくあまりにも原始的な)理解では、モデルとの相互作用(特にその長い操作)を制御するためにビューモデルを使用する必要があります。ただし、ビューモデルは、コードの再利用性を制限するため、アプリケーションの有効期間イベントについて知る必要はありません(Windows 8には、PhoneApplicationServiceなどのクラスはありません)。ここに矛盾がありますか?VMは操作を開始しますが、キャンセルには使用しないでください。

もちろん、Viewは生涯イベントを処理するためにこの責任を負うことができます。そのため、アプリの非アクティブ化に関するイベントは次のように伝播しますView -> ViewModel -> (cancels long operation) -> Model。ただし、ユーザーがビューから移動し、そのビューで開始された操作の一部がまだ実行されている場合、それをキャンセルする方法はありません。ビューはいつでも破棄できます。

ビューモデルでアプリのライフタイムイベントを処理するというアイデアを思いついたのは1つだけです。ただし、前に述べたように、ビューモデルの移植性が制限されるため、このアプローチは嫌いです。誰かがより良い解決策を提供できますか?

4

3 に答える 3

4

ビューモデルでアプリのライフタイムイベントを処理するというアイデアを思いついたのは1つだけです。ただし、前に述べたように、ビューモデルの移植性が制限されるため、このアプローチは嫌いです。誰かがより良い解決策を提供できますか?

私は実際にここで問題を見ていません。MVVMでは、ViewModelは従来、ビューをモデルに結び付ける「接着剤」です。

プラットフォームごとに少量のカスタムViewModelコードがあるからといって、必ずしもViewModelの残りの部分の移植性が制限されるわけではありません。特に、これが抽象化され、プラットフォームごとに独自のプロジェクトに含まれている場合はそうです。

VMは操作を開始しますが、キャンセルには使用しないでください。

これは、VMがそれをキャンセルするものであるべきであることを強く示唆しています。VMがこれらの操作を作成する場合、VMはそれらの所有権を効果的に持ちます。これは、VMがそれらのライフサイクルも管理する必要があることを示唆しています。

于 2013-02-05T18:39:50.003 に答える
1

これがMVVMの原則に違反しているかどうかはわかりませんが、私は単にこのように考えました。

VMでのPhoneApplicationServiceのサブスクリプションに関して、このアプローチを採用しない理由はありますか?

アプリ->ViewModel

アプリはVMの所有者であり、ビューがVMに対して行うように、アプリがインターフェースを介してVMをアクティブ化/非アクティブ化するように指示した場合、VMは再利用性を維持できます。しかし、VMがPhoneApplicationServiceをサブスクライブすると、VMがアプリケーションに依存することを意味します。つまり、VMとアプリケーションは相互に依存し、再利用性が制限されます。

長時間のタスクについては、アプリケーションの有効期間に従って存続する必要があるが、ページの有効期間に従って存続する必要がない場合は、アプリケーションモデルとしてアプリスコープに含めるか、VMから共有できるがページ(ビュー)スコープには含まないものにすることができます。

于 2013-02-06T00:35:34.887 に答える
0

あなたが与える説明は、抽象化の層が欠けていることを私に示唆しています。

特に:

もちろん、ViewModelは、モデルに影響を与える長時間実行イベントを開始できますが、それらの長時間実行イベントに対する所有権はありません。これは正確に真実であり、破られるべきではありません。長時間実行されるイベントを開始する場合(そしてデータベース同期の例はここで非常に優れています)、モデルはこれを処理する必要があります。

ここで欠けている部分は、私が信じているモデルにあります。モデルに影響を与える長時間実行タスクがある場合は、それらを処理する別のレイヤーを用意します。Transaction簡単にするためにそれらを呼び出しましょう。

つまり、モデルドメインで長時間実行するタスクを開始します。次に、モデルはこのタスクを実行します。すべてが正常に機能し、ユーザーまたはシステムの操作によって中断されなかった場合は、タスクデータをモデルに適用できます(またはトランザクションをコミットできます)。

ユーザーまたはシステムが何らかの方法でタスクをキャンセルした場合、モデル内のデータをまったく変更しないでください。モデル自体は変更されません!

一方、モデルが正常に変更された場合は、ViewModelに通知し、ビューを更新する必要があります。しかし、これはあなたがここに持っている実行の2つの主要なブランチのうちの1つにすぎません。そしてそれは、MVVMとViewModelの実装によってすでに処理されているproblabyです。

全体:ビューモデルは、モデルで実行されているタスクを開始およびキャンセルする必要がありますが、特にその存続期間を制御する必要はありません。長時間実行タスクをキャンセルする可能性を提示した場合、キャンセルイベントを発生させることができますが、モデル内のタスクを正常に終了する必要があります。

于 2013-02-05T19:35:19.373 に答える