10

我正在angular-meteor中为管理员构建一个页面。

我已经发布了一个集合中的所有记录:“ posts ”,并且已经订阅了前端的所有记录。

$meteor.subscribe('posts');

在控制器中,如果我从 minimongo 中选择所有记录的游标,它可以正常工作,例如:

$scope.posts = $meteor.collection(Posts);

但我想显示分页,所以我想要一次有限的记录,比如:

$scope.posts = $meteor.collection(function(){

        return Posts.find(

            {}, 
            {
                sort:   {'cDate.timestamp': -1},
                limit:  10
            }
        );
    });

它与 minimongo 中的查询卡住了。浏览器挂起。

posts ”集合仅包含 500 条记录。当我有 200 条记录时,它运行良好。

谁能告诉我我的代码和概念有什么问题?

编辑:

好的!当我像这样从查询中评论$sort行时,它运行良好:

$scope.posts = $meteor.collection(function(){

            return Posts.find(

                {}, 
                {
                    //sort:   {'cDate.timestamp': -1},
                    limit:  10
                }
            );
        });

但我需要对记录进行排序。那我现在该怎么办?

编辑:

还尝试将索引添加到排序属性,如下所示:

db.Posts.ensureIndex({"cDate.timestamp": 1})

还是同样的问题。

4

5 回答 5

3

更改您的出版物以接受这样的pageNumber参数

Meteor.publish('posts', function (pageNumber) {
   var numberOfRecordsPerPage = 10;
   var skipRecords = numberOfRecordsPerPage * (pageNumber - 1);
   return Post.find({
        "user_id": user_id
   }, {
        sort: { 'cDate.timestamp': -1 }
        skip: skipRecords, 
        limit: numberOfRecordsPerPage
   });
});

在客户端,我没有过多地使用 angular-meteor。您可以使用或pageNumber在当前范围内创建属性。每当单击分页页面时更新此变量。每当更改此变量时,请使用当前页码进行订阅。this.pageNumber$scope.pageNumberpageNumber

如果它使用标准 blaze 模板,我会在这样的情况下使用响应式 var 或 session var autorun。在模板 html 中:

<template name="postsTemplate">
     <ul>
         <!-- you would want to do this list based on total number of records -->
         <li class="pagination" data-value="1">1</li>
         <li class="pagination" data-value="2">2</li>
         <li class="pagination" data-value="3">3</li>
     </ul>
</template>

在模板 js 中:

Template.postsTemplate.created = function () {
    var template = this;
    Session.setDefault('paginationPage', 1);
    template.autorun(function () {
       var pageNumber = Session.get('paginationPage');
       Meteor.subscribe('posts', pageNumber);
    });
}

Template.postsTemplate.events(function () {
    'click .pagination': function (ev, template) {
         var target = $(ev.target);
         var pageNumber = target.attr('data-value');
         Session.set('paginationPage', pageNumber);
     }
});

这样,您将在客户端的任何时间点最多有 10 条记录,因此不会导致浏览器崩溃。您可能还想使用类似这样的方式限制发送给客户端的字段

Meteor.publish('posts', function (pageNumber) {
   var numberOfRecordsPerPage = 10;
   var skipRecords = numberOfRecordsPerPage * (pageNumber - 1);
   return Post.find({
        "user_id": user_id
   }, {
        sort: { 'cDate.timestamp': -1 }
        skip: skipRecords, 
        limit: numberOfRecordsPerPage,
        fields: {'message': 1, 'createdBy': 1, 'createdDate': 1 } //The properties inside each document of the posts collection.
   });
});

最后,您将需要客户端的帖子集合中的记录总数,以显示分页链接。您可以使用不同的出版物并使用此处observeChanges官方文档中提到的概念来执行此操作

// server: publish the current size of a collection
Meteor.publish("posts-count", function () {
  var self = this;
  var count = 0;
  var initializing = true;

  // observeChanges only returns after the initial `added` callbacks
  // have run. Until then, we don't want to send a lot of
  // `self.changed()` messages - hence tracking the
  // `initializing` state.
  var handle = Posts.find({}).observeChanges({
    added: function (id) {
      count++;
      if (!initializing)
        self.changed("postsCount", 1, {count: count});
    },
    removed: function (id) {
      count--;
      self.changed("postsCount", 1, {count: count});
    }
    // don't care about changed
  });

  // Instead, we'll send one `self.added()` message right after
  // observeChanges has returned, and mark the subscription as
  // ready.
  initializing = false;
  self.added("postsCount", 1, {count: count});
  self.ready();

  // Stop observing the cursor when client unsubs.
  // Stopping a subscription automatically takes
  // care of sending the client any removed messages.
  self.onStop(function () {
    handle.stop();
  });
});

// client: declare collection to hold count object
PostsCount = new Mongo.Collection("postsCount");

// to get the total number of records and total number of pages
var doc = PostsCount.findOne(); //since we only publish one record with "d == 1", we don't need use query selectors
var count = 0, totalPages = 0;

if (doc) {
    count = doc.count;
    totalPages = Math.ceil(count / 10); //since page number cannot be floating point numbers..
}

希望这可以帮助。

于 2016-02-19T08:21:07.067 回答
2

浏览器崩溃是因为只有这么多数据可以在它自己兑现之前加载到它的缓存中。对于您需要请求大量文档时会发生什么的问题,请将该过程从客户端移开,并通过优化的发布和订阅方法/调用在服务器上执行尽可能多的操作。没有真正的理由在浏览器缓存中加载大量文档,因为 minimongo 的便利性适用于小型数据集和不需要立即与服务器同步(或永远同步)的东西。

于 2016-02-16T06:12:06.847 回答
2

您应该使用服务器端限制而不是客户端。这将使您的应用程序更快并优化。

有关更多信息,请查看此链接。 链接在这里

于 2016-02-23T14:02:41.780 回答
2

您需要考虑排序和限制策略:

如果您要从所有客户端使用的大集合中提取最高值,请在服务器上进行排序。但通常最好先按需要数据的用户过滤,然后对过滤后的集合进行排序。这将减少数据集。

然后将该排序/有限子集发布到客户端,您可以在那里进行更细粒度/排序过滤。

于 2016-02-19T01:51:24.603 回答
2

你应该在服务器端排序,你可以在这里找到你要找的东西

流星发布限制和排序

于 2016-02-18T16:22:52.477 回答