1. ホーム
  2. javascript

[解決済み] MeteorのPublish/Subscribeを理解する

2023-05-29 22:55:24

質問

のリストを表示する簡単なアプリをセットアップしました。 Projects . を削除しました。 autopublish パッケージを削除し、クライアントにすべてを送信しないようにしました。

 <template name="projectsIndex">    
   {{#each projects}}      
     {{name}}
   {{/each}}
 </template>

いつ autopublish をオンにすると、すべてのプロジェクトが表示されるようになります。

if Meteor.isClient
  Template.projectsIndex.projects = Projects.find()

削除されたので、追加でやらなければならない。

 if Meteor.isServer
   Meteor.publish "projects", ->
     Projects.find()
 if Meteor.isClient
   Meteor.subscribe "projects"
   Template.projectsIndex.projects = Projects.find()

ということは、クライアント側の find() メソッドはサーバーサイドからパブリッシュされたレコードのみを検索するということでよろしいでしょうか?というのも、私はこのメソッドを呼び出すのは find() を一度だけ呼び出すべきだと感じたからです。

どのように解決するのですか?

コレクション、パブリケーション、サブスクリプションは、Meteorのトリッキーな部分です。 頻繁に 混乱 によって増幅されることがあります。 紛らわしい専門用語 .

ここでは Sacha Greif (の共著者です。 ディスカバー メテオ )が、出版物と購読を1枚のスライドで説明しています。

を呼び出す必要がある理由を正しく理解するために find() を複数回呼ぶ必要があるのかを正しく理解するためには、Meteorでコレクション、パブリケーション、サブスクリプションがどのように動作するのかを理解する必要があります。

  1. MongoDBでコレクションを定義します。Meteorはまだ関係ない。これらのコレクションには データベースのレコード (Mongoではドキュメントとも呼ばれます) やMeteorでは しかし、quot;document" はデータベースのレコードよりも一般的なもので、例えば、更新仕様やクエリセレクタは document - を含む JavaScript オブジェクトです。 field: value のペアを含む)。

  2. 次に コレクション をMeteorサーバ上で定義します。

    MyCollection = new Mongo.Collection('collection-name-in-mongo')
    
    

    これらのコレクションには すべて を含むので、MongoDB コレクションのデータから MyCollection.find({...}) を実行し、その結果 カーソル (レコードの集合で、それらを反復処理し、返すメソッドを持つ)。

  3. このカーソルは(たいていの場合)次のように使われます。 を発行する (送信) レコードのセット (これを "レコードセット"。 ). オプションで 一部 のフィールドをそれらのレコードから取得します。それはレコードセット( ではなく コレクションではありません) であり、クライアントが サブスクライブ になります。公開は パブリッシュ機能 これは、新しいクライアントが購読するたびに呼び出され、どのレコードを返すかを管理するためのパラメータを取ることができます(例えば、そのユーザのドキュメントだけを返すためにユーザIDを指定するなど)。

  4. クライアントで を指定すると Minimongo というコレクションがあります。 部分的に ミラー 一部 は、サーバーからのレコードの一部です。 "一部" は、フィールドの一部だけを含むことがあるからで、"一部のレコード" は、通常、ページの読み込みを速くするために、クライアントが必要とするレコードだけを送信したいからで、必要とするものだけ がアクセスする権限を持っているレコードのみをクライアントに送信したいからです。

    <ブロッククオート

    Minimongo は基本的にインメモリで非永続的な Mongo の実装で、純粋な JavaScript です。このクライアントが扱うデータベースのサブセットだけを保存するローカルキャッシュとして機能します。クライアントからの問い合わせ (find) は、サーバーに問い合わせることなくこのキャッシュから直接行われます。

    これらのMinimongoのコレクションは、最初は空っぽです。このコレクションを埋めるのは

    Meteor.subscribe('record-set-name')
    
    

    の呼び出しがあります。なお、パラメータに サブスクライブ のパラメータはコレクション名ではなく レコードセット の名前であり、サーバーが publish の呼び出しに使われたレコードセットです。は subscribe() の呼び出しは、クライアントに レコードセット - サーバコレクションからのレコードのサブセット (たとえば直近の 100 件のブログ記事) を、各レコードのフィールドのすべてあるいは部分集合 (たとえば titledate ). Minimongoは受信したレコードをどのコレクションに入れるかどうやって知るのですか?コレクションの名前は collection 引数は、パブリッシュハンドラの added , changed そして removed コールバックがない場合 (ほとんどの場合そうです)、サーバー上の MongoDB コレクションの名前になります。

レコードの修正

クライアントでMinimongoコレクションのレコード(ドキュメント)を変更すると、Meteorはそれに依存するすべてのテンプレートを即座に更新し、サーバーにも変更を送り返します。サーバーは変更をMongoDBに保存し、そのドキュメントを含むレコードセットを購読している適切なクライアントに送信します。これを 遅延補償 のひとつで の7つの基本原則の1つであり、Meteorの .

複数のサブスクリプション

異なるレコードを取り込むたくさんのサブスクリプションを持つことができますが、それらはすべて、サーバー上の同じコレクションから来たものであれば、クライアント上の同じコレクションに収められます。 _id . これは明確に説明されていませんが、Meteorのドキュメントでは暗黙の了解になっています。

レコードセットを購読すると、サーバにレコードをクライアントに送信するように指示します。クライアントはこれらのレコードをローカルのMinimongoコレクションに格納し、その名前は collection 引数で指定された名前で保存されます。 added , changed そして removed のコールバックがあります。Meteorは、クライアントで一致するコレクション名を持つMongo.Collectionを宣言するまで、受信した属性のキューに入れます。

説明されていないのは、次のような場合にどうなるかです。 しない を明示的に使用した場合 added , changedremoved を使うか、あるいはまったく発行ハンドラを使わない場合 - これがほとんどの場合です。この最も一般的なケースでは、collection 引数は (当然ながら) ステップ 1 でサーバー上で宣言した MongoDB コレクションの名前から取られます。しかし、これはつまり、異なる名前の出版物や購読物を用意しても、すべてのレコードがクライアント上の同じコレクションに収まるということです。のレベルまで トップレベルフィールド Meteorは、サブスクリプションが重なり合うことができるように、ドキュメント間のセットユニオンを実行するように配慮しています。クライアントに異なるトップレベルフィールドを出荷するパブリッシュ関数が並んで働き、クライアントでは、コレクション内のドキュメントが、