angularjs - 从大量记录的minimongo查询挂起浏览器

标签 angularjs meteor publish-subscribe angular-meteor minimongo

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

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

$meteor.subscribe('posts');

在 Controller 中,如果我从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
                }
            );
        });

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

编辑:

还尝试过将索引添加到sort属性,如下所示:
db.Posts.ensureIndex({"cDate.timestamp": 1})

还是同样的问题。

最佳答案

更改您的发布以接受一个名为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 的合作不多。您可以使用pageNumberthis.pageNumber在当前作用域下创建$scope.pageNumber属性。每当单击您的分页页面时,请更新此pageNumber变量。每当更改此变量时,请使用当前页码进行订阅。

如果它使用的是标准blaze模板,则可以使用像这样的autorun中的响应式(Reactive)var或session var来实现。
在模板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.
   });
});

最后,您将需要客户端上的帖子集合中的记录总数,以显示分页链接。您可以使用其他出版物以及官方文档here中提到的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..
}

希望这可以帮助。

关于angularjs - 从大量记录的minimongo查询挂起浏览器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35194437/

相关文章:

python - Redis channel 中 PUB/SUB 时消息的大小限制是多少

javascript - 使用 javascript .link() 方法打开弹出窗口

angularjs - 将 FireBaseAuthClient 与 AngularJS 结合使用时为 "Error: $apply already in progress"

css - 获取div angular js的高度

javascript - 范围变量应用问题期间的 Angular 快速单击

javascript - Meteor 个人资料页面检查当前用户是否是页面所有者

javascript - 显示来自 Meteor 1.0 的数据

ruby-on-rails - 如何在 redis rails 中订阅多个发布者?

mongodb - Mongo 在 Meteor 应用程序的 _id_ 字段上给出重复键错误

publish-subscribe - CQRS + 事件溯源 : (is it correct that) Commands are generally communicated point-to-point, 而领域事件通过发布/订阅进行通信?