0

Meteor js を開始したばかりで、公開方法に苦労しています。以下は、公開方法の 1 つです。

//サーバ側

Meteor.publish('topPostsWithTopComments', function() {
  var topPostsCursor = Posts.find({}, {sort: {score: -1}, limit: 30});
  var userIds = topPostsCursor.map(function(p) { return p.userId });

  return [
    topPostsCursor,
    Meteor.users.find({'_id': {$in: userIds}})
  ];
});

// クライアント側

Meteor.subscribe('topPostsWithTopComments');

現在、クライアントでパブリッシュ データを使用する方法がわかりません。私はtopPostsWithTopCommentsによって与えられるデータを使いたいと思っていました

問題は以下に詳述されています

新しい投稿がトップ 30 リストに入ると、次の 2 つのことが必要になります。

The server needs to send the new post to the client.
The server needs to send that post’s author to the client.

Meteor は 6 行目に返された投稿カーソルを監視しているため、新しい投稿が追加されるとすぐに送信され、クライアントが新しい投稿をすぐに受信できるようになります。

ただし、7 行目に返された Meteor.users カーソルについて考えてみましょう。カーソル自体がリアクティブであっても、現在は userIds 配列に古い値を使用しています (これは単純な古い非リアクティブ変数です)。つまり、その結果セットは次のようになります。同様に時代遅れです。

これが、そのカーソルに関する限り、クエリを再実行する必要がなく、Meteor が元の 30 のトップ投稿に対して同じ 30 人の著者を無限に公開し続ける理由です。

そのため、パブリケーションのコード全体を (userId の新しいリストを作成するために) 再度実行しない限り、カーソルは正しい情報を返さなくなります。

基本的に私が必要とするのは:

Post で変更が発生した場合は、更新されたユーザー リストが必要です。ユーザーコレクションを再度呼び出す必要はありません。ユーザーの完全な mrt モジュールをいくつか見つけました。 リンク1 | リンク2 | リンク3

あなたの意見を共有してください!

-ニーレシュ

4

2 に答える 2

1

サーバー上でデータを公開するときは、クライアントがクエリを許可されているものを公開しているだけです。これはセキュリティのためです。パブリケーションをサブスクライブした後でも、パブリケーションが何を返したかを照会する必要があります。

if(Meteor.isClient) {
    Meteor.subscribe('topPostsWithTopComments');
    // This returns all the records published with topPostsWithComments from the Posts Collection
    var posts = Posts.find({});
}

現在のユーザーが所有する投稿のみを公開したい場合は、クライアントではなくサーバーの publish メソッドでそれらを除外する必要があります。

于 2014-08-01T12:41:22.870 に答える
0

@Will Brock はすでにあなたの質問に答えていると思いますが、抽象的な例でより明確になるかもしれません。

collectionaとという名前の 2 つのコレクションを作成しましょうcollectionb

// server and client
CollectionA = new Meteor.Collection('collectiona');
CollectionB = new Meteor.Collection('collectionb');

サーバー上でと を別々に呼び出して、両方のレコード セットをクライアントに公開できるようMeteor.publishになりました。このようにして、クライアントはそれらに個別にサブスクライブすることもできます。'collectiona''collectionb'

Meteor.publishただし、代わりに、配列内の複数のカーソルを返すことにより、1 回の呼び出しで複数のレコード セットを公開することもできます。標準の公開手順と同様に、クライアントに送信する内容をもちろん定義できます。そのようです:

if (Meteor.isServer) {
  Meteor.publish('collectionAandB', function() {
    // constrain records from 'collectiona': limit number of documents to one
    var onlyOneFromCollectionA = CollectionA.find({}, {limit: 1});

    // all cursors in the array are published
    return [
      onlyOneFromCollectionA,
      CollectionB.find()
    ];
  });
}

クライアントでは'collectiona''collectionb'個別にサブスクライブする必要はありません。代わりに、単に購読することができます'collectionAandB':

if (Meteor.isClient) {
  Meteor.subscribe('collectionAandB', function () {
    // callback to use collection A and B on the client once 
    // they are ready

    // only one document of collection A will be available here
    console.log(CollectionA.find().fetch()); 

    // all documents from collection B will be available here
    console.log(CollectionB.find().fetch());
  });
}

したがって、理解する必要があるのは、Meteor.publish呼び出しで発行された 2 つのカーソルを含む配列がクライアントに送信されないことです。これは、呼び出しに引数として渡された関数でカーソルの配列を返すと、配列にMeteor.publish含まれるすべてのカーソルを公開するよう Meteor に指示するだけだからです。クライアントでコレクション ハンドルを使用して個々のレコードをクエリする必要があります (@Will Brock の回答を参照)。

于 2014-08-01T13:36:51.260 に答える