我正在 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 的合作不多。您可以使用
pageNumber
或this.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/