これが一般的なアプローチです。
- AMD について学ぶことに時間を費やしてください。require.js はまさにそのための優れたライブラリです。
- ビューモデルを別々に保ち、それらを結合しないでください。
- knockout-postbox、amplify.js pub/sub は、相互の通信に最適です。
- シングル ページ アプリケーション フレームワークを見てください。デュランダルは素晴らしい選択肢です。
- Durandal や SPA を使用する予定がない場合でも、ノックアウトでバインドを処理する別のモジュールを作成してください。
- 各ビューには、対応するビューモデルが必要です。
- ajax 呼び出しを独自のモジュールに分離します。例: TouristRepository.js は、すべての ajax 呼び出しを行うモジュールである可能性があります。
- Promise を使用します。Q.js または jquery の延期された約束が役に立ちます。リポジトリは promise を返す必要があります。
- あなたのビューモデルはまさにそれであるべきです...本質的に、それは状態を保持し、ビュー相互作用ハンドラーを提供する必要があります。モデルは独自のファイルである必要があります。その後、ViewModel はモデル データを保持できます。
- モデル データは、リポジトリ経由でのみ取得する必要があります。
これはまともなアプローチであり、あなたにとってうまくいくものだと思います。
編集 - コメントに基づいてさらに追加します。
1) define を使用する代わりに、requirejs でシミングとエクスポートを使用して ko 検証プラグインをロードできます。そもそもrequirejsを使用してロードしていない場合を除きます。
2) pub/sub の使用はカップリングではありません。結合は、あるモジュールが別のモジュールの機能または存在に完全に依存している場合に発生します。MasterViewModel が別のビューモデルと直接通信していることを考慮すると、カップリングです。pub/sub シナリオでは、1 つのビューモデル (Persons.js と呼びます) は、人物オブジェクトを保存することです。保存すると、ローカルキャッシュが更新されるはずです。この場合、Persons.js は、保存後に「Person saved」というメッセージを送信し、保持しているデータを渡します。ClearCache.js は、キャッシュのクリアを担当するものです。「人が保存されました」というメッセージをリッスンして何らかのアクションを実行するだけです。結合された方法は、Persons.js が ClearCache をインスタンス化し、その clearCache メソッドを直接呼び出すことです。したがって、Persons.js が存在するためには、clearCache.js が存在する必要があります。ただし、pub/sub では、clearCache.
3) この質問に対する答えは、アプリケーションの要件によって異なります。通常、binder.js という中間モジュールがあります。バインダー.js、メッセージをリッスンします。たとえば、ユーザーが詳細な情報を見たいと思っており、観光客をクリックしたとします。TouristsViewModel は、「Tourist Detail Requested」というメッセージを発行し、観光客 ID または何らかの情報を渡します。これをリッスンしているバインダーは、インスタンス化するビューモデルと実行するアクションを認識しています。そうすれば、TouristsViewModel は TouristsInfoViewModel を完全に認識しません。別のビューで、すべての観光客の firstNames と lastNames を一覧表示していて、詳細を表示する必要がない場合は、不必要に TouristsInforViewModel を取り込むことなく TouristsViewModel を再利用できます。この場合、MasterViewModel は必要ありません。
あなたのアプリケーションは、シングル ページ アプリケーションの最適な候補のように思えます。「One View - One ViewModel」アプローチと「Single Responsibility」アプローチに従います。TouristsViewModel は観光客のみを表示し、TouristInfoViewModel は観光情報を表示します。両者はお互いに何の見当もつかない。私は最近、同様の要件を持つプロジェクトに取り組みました。スピーカー、スピーカーの詳細、セッション、セッションの詳細。私のビューモデルはどれも他のビューモデルを知りません。それらはすべて、クライアント側のルートとハッシュ変更イベントを介して管理されます。