Meteor:过滤一个已发布的完整集合,其中包含延迟加载限制

时间:2017-02-22 09:37:46

标签: meteor

我有一系列帖子,我想以块(也称为分页/延迟加载)加载。但我也想:

  1. 搜索所有帖子
  2. 或者加载并显示所有具有属性' important'该集合没有限制。
  3. 我还没有与多个集合或订阅相处,所以我没有在服务器代码中设置.publish()中的限制,而是在客户端进行了设置。看起来像这样:

    // Server side
    export const Posts = new Mongo.Collection('posts');
    if (Meteor.isServer) {
      Meteor.publish('posts', function () {
        return Posts.find({}, {
          sort: {createdAt: -1}
        });
      });
    }
    
    //Client side
    export default createContainer(() => {
      Session.setDefault('lazyloadLimit', 10);
      Meteor.subscribe('entrys');
    
      return {
        posts: Posts.find({}, { sort: { createdAt: -1 }, limit: Session.get('lazyloadLimit') }).fetch(),
        importantPosts: Posts.find({important: true}, {sort: { createdAt: -1 }}).fetch(),
        importantPostsCount: Posts.find({important: true}).count(),
      };
    }, App);
    

    结果看起来正确,但现在我的主要问题是:这会将所有帖子加载到客户端,还是只加载限制内的那些?我想它会加载所有帖子,仅限限制用于渲染时间,但不用于带宽。

    只是为了完成:我之前的尝试看起来像这样,但我无法进入ImportantPosts集合:

    // Server side
    export const Posts = new Mongo.Collection('entrys');
    export const ImportantPosts = new Mongo.Collection(null); // <- where do I put this?
    
    if (Meteor.isServer) {
      Meteor.publish('posts', function (limit) {
        return Posts.find({}, {
          limit: limit,
          sort: {createdAt: -1}
        });
      });
    
      Meteor.publish('importantPosts', function () {
        return Posts.find({important: true}, {
          sort: {createdAt: -1}
        }); // <- how do I get these into ImportantPosts-collection?
      });
    }
    
    // Client side
    export default createContainer(() => {
    
      Session.setDefault('lazyloadLimit', 10);
      Tracker.autorun(function(){
        Meteor.subscribe('posts', Session.get('lazyloadLimit'));
      });
      Meteor.subscribe('importantPosts');
    
      return {
        entrys: Posts.find({}, { sort: { createdAt: -1 }, limit: Session.get('lazyloadLimit') }).fetch(),
        importantPosts: ImportantPosts.find({}, {sort: { createdAt: -1 }}).fetch(),
        importantPostsCount: ImportantPosts.find({}).count(),
      };
    }, App);
    

2 个答案:

答案 0 :(得分:2)

让我们谈谈这些2做了什么,从你之前的尝试,但称之为“帖子”:

  export const Posts = new Mongo.Collection('posts');

  Meteor.publish('posts', function (limit) {
    return Posts.find({}, {
      limit: limit,
      sort: {createdAt: -1}
    });
  });

  Meteor.publish('importantPosts', function () {
    return Posts.find({important: true}, {
      sort: {createdAt: -1}
    }); // <- how do I get these into ImportantPosts-collection?
  });
第一,显然,发布所有帖子。第二个发布所有帖子的子集。因为第二个是多余的。 (从客户端,您将对集合'帖子'进行所有处理。)Meteor将其称为“合并框”:它将来自同一集合的所有已发布项目组合到同一“框”中。即它是来自同一集合的所有出版物的联合。

首次发布的缺点是您将所有帖子发布到所有客户端,以便您可以进行搜索。这可能是很多数据。你已经提到了分页,所以从概念上来说这将有助于你正在尝试做什么。

查看我上面粘贴的代码,您将2个发布语句视为2个独立的集合,当它们确实是1时。让我们继续考虑这一点。

你想做所有这些:

  1. 页面帖子
  2. 显示所有重要帖子
  3. 搜索帖子
  4. 让我们从#3开始。我将声明应该在服务器上完成。您可以编写一个流星方法来使用用户的搜索词进行搜索,而该流星方法可以简单地发布结果,而不是返回该数据。 Meteor的合并框将确保您的客户现在拥有这些帖子,以及它已有的任何帖子。

    所以在搜索时,现在您的客户只需要按搜索值进行过滤,它应该可以正常工作。

    现在#2:您已经编写了发布,过滤了important = true。如果您在客户端上订阅,那么这些结果将写入合并框。

    离开你已经写过的#1。当您的用户通过帖子页面时,所有这些都将被写入合并框。

    所以你的客户除了订阅2件事并进行方法调用之外,现在只需处理基于用户的过滤,搜索,要求查看重要事项或两者(即搜索重要信息)那些)。

    并且所有这些操作都将在集合'posts'上。

    这样做的最终结果是,不是一次加载所有帖子,而是逐步加载它们作为用户页面。所以除非他们浏览所有页面,否则用户不会收到所有帖子。

答案 1 :(得分:0)

我刚刚发现的解决方案似乎有用(我不了解它是如何工作的)可能Find From Publication看起来像这样:

$ meteor add percolate:find-from-publication

-

// Server side
export const Posts = new Mongo.Collection('posts');

if (Meteor.isServer) {
  Meteor.publish('posts', function (limit) {
    return Posts.find({}, {
      limit: limit,
      sort: {createdAt: -1}
    });
  });
  FindFromPublication.publish('importantPosts', function () {
    return Posts.find({important: true}, {
      sort: {createdAt: -1}
    });
  });
}

// Client side
export default createContainer(() => {
  Session.setDefault('lazyloadLimit', 10);
  Tracker.autorun(function(){
    Meteor.subscribe('posts', Session.get('lazyloadLimit'));
  });
  Meteor.subscribe('importantPosts');

  return {
    posts: Posts.find({}, { sort: { createdAt: -1 }, limit: Session.get('lazyloadLimit') }).fetch(),
    importantPosts: Posts.findFromPublication('importantPosts', {}, {sort: { createdAt: -1 }}).fetch(),
    importantPostsCount: Posts.findFromPublication('importantPosts', {}).count(),
  };
}, App);