我正在 angular-meteor 中为管理员构建一个页面。
我发布了来自集合的所有记录:" 帖子"并且已经采用了前端所有记录的订阅。
$meteor.subscribe('posts');
在控制器中,如果我从minimongo中选择所有记录的游标,它可以正常工作:
$scope.posts = $meteor.collection(Posts);
但是我想要显示分页,所以我想要一次有限的记录,如:
$scope.posts = $meteor.collection(function(){
return Posts.find(
{},
{
sort: {'cDate.timestamp': -1},
limit: 10
}
);
});
它在minimongo中遇到了查询。浏览器挂起了。
"的帖子"集合仅包含500条记录。当我有200条记录时它工作正常。
任何人都可以告诉我一个关于我的代码和概念有什么问题的想法吗?
编辑:
好!当我从查询中评论 $ sort 行时,它运行正常:
$scope.posts = $meteor.collection(function(){
return Posts.find(
{},
{
//sort: {'cDate.timestamp': -1},
limit: 10
}
);
});
但我需要对记录进行排序。那我现在该怎么办?
修改
还尝试在sort属性中添加索引,如下所示:
db.Posts.ensureIndex({"cDate.timestamp": 1})
还是同样的问题。
答案 0 :(得分: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
});
});
在客户端,我没有使用角度流星。您可以使用pageNumber
或this.pageNumber
在当前范围下创建$scope.pageNumber
媒体资源。每次单击分页页面时,都会更新此pageNumber
变量。每当更改此变量时,请使用当前页码进行订阅。
如果它使用的是标准的blaze模板,我会使用autorun
中的反应式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..
}
希望这有帮助。
答案 1 :(得分:2)
浏览器崩溃,因为只有这么多数据可以在它自己兑现之前加载到它的缓存中。关于当您需要大量文档时会发生什么的问题,请将该过程从客户端移开,并通过优化的发布和订阅方法/调用在服务器上执行相同的操作。没有理由在浏览器缓存中加载大量文档,因为最小的方便是小数据集和不需要立即与服务器同步(或永远同步)的东西。
答案 2 :(得分:2)
你应该在服务器端排序,你可以在这里找到你想要的东西
答案 3 :(得分:2)
您需要考虑排序和限制策略:
如果要从所有客户端使用的大集合中提取最高值,请在服务器上进行排序。但通常最好先由需要数据的用户进行过滤,然后对过滤后的集合进行排序。这将减少数据集。
然后将已排序/有限的子集发布到客户端,您可以在那里进行更细粒度/排序过滤。
答案 4 :(得分:2)
您应该使用服务器端限制而不是客户端。这将使您的应用更快,更优化。
有关详情,请查看此链接。 link here