Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
381 views
in Technique[技术] by (71.8m points)

subscriptions - Overlapping Meteor publications

I have a meteor app which has 2 publications for posts. One for all posts and one for featured posts. There are 2 featured posts - "Post 1" and "Post 4". I show featured posts on all pages, while i paginate all posts (including the featured posts) sorted by name. When i travel between pages, the data from the 2 publications get mixed up and show incorrect results.

Here is the code:

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
    }
  });
});

On the client I am subscribing to both and displaying the data in 2 loops

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 is as follows:

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

The problem is the data from the 2 subscriptions are getting mixed up in the display.

On page 1 it shows it correctly:

Page 1

Featured
  post 1
  post 4

All Posts
  post 1
  post 2
  post 3

but when I go to page 2

Page 2

Featured
  post 1
  post 4

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

It shows "post 1" inside the "posts" which is featured but shouldn't be on page 2. When I go to page 3, i see "post 1" and "post 4" but they should not be there.

I understand how the publications and subscriptions work and why this is happening - because the publications merges the dataset. I am wondering if there is a work around to keep them separate?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If I understand correctly, your pages correspond to pagination of your "All Posts" list. The "page" number is sent as your subscription parameter, so that you receive a short list of your posts.

The difficulty here is indeed that your Client collection does not have all your documents in hand (since you limit them in your 'posts' publication), so you cannot use a similar skip logic as in the publication.

As proposed in Meteor Guide > Paginating subscriptions, you could use the percolate:find-from-publication Atmosphere package to easily retrieve the documents that come from your 'posts' publication, and only them.

// 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)
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...