余裕があれば、2 つのケースを 1 つの投影に「結合」すると思います。それは物事を劇的に単純化するでしょう。しかし、次の点を理解することは非常に重要です。
クエリ プロジェクションの結果をエンティティに変換する必要はありません。
バックグラウンド: CCJS の例
おそらく、John Papa の優れた PluralSight コース「 Single Page Apps JumpStart 」の CCJS の例から、エンティティへの射影手法について学習したことでしょう。CCJS は、非常に具体的な理由でこの手法を使用します。サーバーにアクセスせずにリストの更新を簡素化するためです。
プロジェクション クエリによって入力される CCJS "Sessions List" を考えてみましょう。John は、クエリの結果をエンティティに変換する必要はありませんでした。彼は、予測された結果に直接バインドできた可能性があります。Knockout は生のデータ値に喜んでバインドすることを思い出してください。ユーザーがそのリストのセッションを直接編集することはありません。表示されたセッション値を変更できない場合、それらを監視可能なプロパティに変換すると、CPU が無駄になります。
セッションをタップすると、完全なセッション エンティティのほぼすべてのプロパティにアクセスできるセッション ビュー/編集画面に移動します。CCJS はそこに完全なエンティティを必要とするため、キャッシュ内の完全な (部分的ではない) セッションを探し、見つからない場合はサーバーからエンティティを読み込みます。この時点でも、以前に元の投影結果を (部分的な) セッション エンティティに変換したことに特に価値はありません。
セッションを編集し、タイトルを変更して保存します。「セッション一覧」に戻る
質問
更新されたタイトルがセッション リストに表示されることを確認するにはどうすればよいですか?
セッション リスト HTML をプロジェクション データ オブジェクトにバインドした場合、それらのオブジェクトはエンティティではありません。それらは単なるオブジェクトです。セッション ビューで編集したエンティティは、セッション リストに表示されるコレクションのオブジェクトではありません。はい、リストに対応するオブジェクトがあります - 同じセッションを持つオブジェクトid
です。しかし、それは同じオブジェクトではありません。
選択肢
#1 : 射影クエリを再発行して、サーバーからリストを更新します。投影データに直接バインドします。データは、エンティティではなく生の JavaScript オブジェクトで構成されていることに注意してください。それらは Breeze キャッシュにはありません。
#2 : 実際のセッション エンティティを保存した後にイベントを発行します。サブスクライブしている「Sessions List」ViewModel はイベントを受信し、変更を抽出して、リスト内のセッションのコピーを更新します。
#3 : どこでもセッション エンティティを使用できるように、エンティティへの射影手法を使用します。
長所と短所
#1は実装が簡単です。ただし、Sessions List ビューに入るたびにサーバートリップが必要です。
CCJS の設計目標の 1 つは、一度読み込まれると、サーバーへのアクセスなしで完全にオフラインで操作できるようにすることでした。接続が断続的で貧弱な場合でも、サクサク動作するはずです。
CCJS は、いつでも会議に参加できるガイドです。いつ、どこで、どのセッションが利用できるかがすぐにわかるので、ホールを歩いているときに目的のセッションを見つけて、そこにたどり着くことができます。技術会議やホテルに行ったことがあれば、wifi は一般的にひどいものであり、サーバーに直接アクセスできる場合にのみ機能する場合、アプリはほとんど役に立たないことを知っています。
#1 は、CCJS の意図した動作環境にはあまり適していません。
CCJS ジャンプスタートは、その「サーバーに依存しない」パスの途中にあります。すぐに、完全なオフライン実装に近いものが表示されます。
また、関連するエンティティに移動することもできなくなります。セッション リストには、各セッションのトラック、タイムスロット、ルームが表示されます。これは、「ルックアップ」参照エンティティで見つかった反復情報です。プロジェクションを拡張して、この情報をセッションの「フラットな」ビューに含めるか (より太いペイロード)、クライアント側で巧妙になり、手動でトラック、タイムスロット、およびルーム データにパッチを適用する必要があります (複雑さ)。
#2は、オフライン/断続的な接続シナリオに役立ちます。もちろん、メッセージング システムをセットアップし、保存されたエンティティに関するプロトコルを確立し、影響を受けるセッション プロジェクション オブジェクトを見つけて更新するようにセッション リストに教える必要があります。それはそれほど難しいことではありません - BreezeEntityManager
が発行するイベントで十分かもしれません - しかし、それにはさらに多くのコードが必要です。
#3は「サーバーの独立性」に適しており、プロジェクションペイロードが小さく、非常に簡単で、そよ風のクールなデモンストレーションです. isPartial
キャッシュ内のセッションが完了しているかどうかを常に把握できるように、フラグを管理する必要があります。それは難しいことではありません。
「部分エンティティ」の複数のフレーバーが必要な場合は、さらに複雑になる可能性があります...これは、あなたが行っているようです。それは CCJS では問題ではありませんでした。
アプリケーションの目的に適合するため、John は CCJS に #3 を選択しました。
これは、すべてのアプリケーションにとって正しい選択ではありません。それはあなたにとって正しい選択ではないかもしれません。
たとえば、常に高速で低遅延の接続を使用している場合は、#1 が最適な選択肢になる可能性があります。本当にわかりません。
キャストからエンティティへのアプローチは簡単で、ほとんどの場合うまく機能するので気に入っています。その選択をする前に、私はその選択についてよく考えます。
概要
- 射影クエリの結果をエンティティに変換する必要はありません
- 読み取り専用の場合、Knockout の監視可能なプロパティを使用せずに、投影されたデータに直接バインドできます
- 投影されたデータを (部分的な) エンティティに変換する十分な理由があることを確認してください。
CCJS には、射影されたクエリ データをエンティティに変換する正当な理由があります。あなたは?