2017-05-16 5 views
1

私は、投稿のための2つの出版物を持つ流星のアプリを持っています。 1つはすべての投稿用、1つは特集記事用です。ポスト1とポスト4の2つの特集記事があります。すべてのページに特集記事を表示していますが、投稿ごとに投稿された投稿を名前で並べ替えて表示しています。ページ間を移動すると、2つのパブリケーションのデータが混ざり合って正しくない結果が表示されます。次のようにクライアントで重複する流星の出版物

Meteor.publish('posts', function(page) { 
    const skip = parseInt(page && page !== '' ? page : 0) * 3 
    return Posts.find({}, { 
    limit: 3, 
    skip, 
    sort: { 
     name: 1 
    } 
    }); 
}); 

Meteor.publish('featured', function() { 
    return Posts.find({ 
    featured: true 
    }, { 
    sort: { 
     name: 1 
    } 
    }); 
}); 

私は両方に加入し、2つのループ

Template.hello.onCreated(function helloOnCreated() { 
    const instance = this; 
    instance.autorun(function() { 
    instance.subscribe('posts', FlowRouter.getParam('page')) 
    instance.subscribe('featured') 
    }); 
}); 

Template.hello.helpers({ 
    posts() { 
    return Posts.find({}, { 
     limit: 3, 
     sort: { 
     name: 1 
     } 
    }) 
    }, 
    featured_posts() { 
    return Posts.find({ 
     featured: true 
    }, { 
     sort: { 
     name: 1 
     } 
    }); 
    } 
}); 

にデータを表示していますHTMLテンプレートです:

<template name="hello"> 
    <h2>Featured</h2> 
    {{#each featured_posts}} 
    {{> post}} 
    {{/each}} 
    <h2>Posts</h2> 
    {{#each posts}} 
    {{> post}} 
    {{/each}} 
</template> 
ここ

は、コードがあります

問題は、2つのサブスクリプションのデータがディスプレイに混在していることです。

Page 1 

Featured 
    post 1 
    post 4 

All Posts 
    post 1 
    post 2 
    post 3 

を私は2ページ

Page 2 

Featured 
    post 1 
    post 4 

All Posts -- Should be 
    post 1  post 4 
    post 4  post 5 
    post 5  post 6 

に行くとき、それは "ポスト1" 内側紹介され、 "ポスト" が、shouldn」を示している:1ページ

それはそれを正しく示して私はページ3に行くとき、私は "ポスト1"と "ポスト4"を参照してくださいが、彼らはそこにすべきではありません。

パブリケーションとサブスクリプションがどのように機能し、なぜこれが起こっているのかを理解しています。パブリケーションがデータセットをマージするためです。それらを別々に保つための回避策があるかどうか疑問に思っていますか?

答えて

1

私が正しく理解していれば、あなたのページはあなたの「すべての投稿」リストのページ付けに対応しています。 「ページ」番号がサブスクリプションパラメータとして送信されるので、短いリストの投稿を受け取ることができます。

難易度はここに(あなたが'posts'出版物でそれらを制限するため)あなたのクライアントのコレクションが手にすべてのドキュメントを持っていないことを確かなので、あなたが出版物と同様のskipのロジックを使用することはできません。流星ガイドで提案されているように

>Paginating subscriptions、簡単にあなたの'posts'出版から来る、とだけそれらの文書を取得するためにpercolate:find-from-publication雰囲気のパッケージを使用することができます。

// Server 
FindFromPublication.publish('posts', function(page) { 
    // Same logic 
    const skip = parseInt(page && page !== '' ? page : 0) * 3 
    return Posts.find({}, { 
    limit: 3, 
    skip, 
    sort: { 
     name: 1 
    } 
    }); 
}); 

// Client (no change in subscription) 
Template.hello.helpers({ 
    posts() { 
     return Posts.findFromPublication('posts', {}, { 
     sort: { 
      name: 1 
     } 
     }); 
    } // (no change in featured_posts) 
}); 
1

公表されたデータは、クライアント上で単離することができるように、私はobserve or observeChangesを使用してお勧めします。ドキュメントは威圧的かもしれませんが、見た目よりも実際には簡単です。

特別なクライアント側のコレクションを作成し、observeコールバックでそのコレクションの名前を使用するだけです。クライアント側のコレクション名は、"featured_posts"は、刊行物にself.addedself.changedself.removedへの呼び出しで使用されていることに注意してください:

// client-side 
const FeaturedPosts = new Mongo.Collection('featured_posts', { 
    defineMutationMethods: false 
}); 

// server-side 
Meteor.publish('featured', function() { 
    const self = this; 

    const handle = collection.find(selector, opts).observe({ 
     added: function(doc) { 
     self.added('featured_posts', doc._id, doc); 
     }, 

     changed: function(newDoc, oldDoc) { 
     self.changed('featured_posts', newDoc._id, newDoc); 
     }, 

     removed: function(doc) { 
     self.removed('featured_posts', doc._id); 
     }, 
    }); 

    self.ready(); 

    self.onStop(function(err) { 
     if (!err) { 
     handle.stop(); 
     } 
    }); 
    }); 
}; 
+0

コレクションヘルパーでこの仕事をしていますか? – Addy

+0

私はコレクションヘルパーを使用していないが、変換関数を登録するだけであると考えると、変換関数が動作するところ、つまり 'observe'があればどこでも動作することを期待しています。 docsから。 "変換は、observeChangesのコールバックまたは発行関数から返されたカーソルには適用されません。" –

+1

他のコレクションからデータを「結合」する必要がある場合は、コールバックで必要なカスタムロジックを実行できます。さらに、変換関数を渡して/ findOneを検索し、コレクションレベル変換をオーバーライドすることもできます。 –