我遇到了已经实施的分页问题。分页工作基于服务器端发布skip&限制过滤器。
在该状态下,skip设置为0,limit始终为20.
如果我执行find()。fetch(),我会得到20个元素,但它们都是针对不同的用户。
这是一种非常奇怪的行为。 服务器端发布
Meteor.publish('overtime', function(opt){
if (!Roles.userIsInRole(this.userId, 'admin')) {
return Overtime.find({userId: this.userId}, opt);
} else {
return Overtime.find({}, opt);
}
});
客户端订阅
var defaultSkipStep = 10;
var defaultLimit = 20;
Template.triphtml.onCreated(function(){
var instance = this;
Session.set('limit',defaultLimit);
instance.autorun(function(){
instance.subscribe('overtime', {skip:(Session.get('overSkip')||0), limit:(Session.get('limit')||defaultLimit), sort: {createdAt: -1}});
instance.subscribe('trips', {skip:(Session.get('tripSkip')||0), limit:(Session.get('limit')||defaultLimit), sort: {createdAt: -1}});
});
下一页点击事件
"click .nxtpage_over": function(event, template){
Session.set('overSkip', (Session.get('overSkip') || 0) + defaultSkipStep);
Session.set('limit', 20);
},
提交活动 https://pastebin.com/btYCSQBD
用户看到的查询 main.js(客户端)
main.html中 https://pastebin.com/4uMVFsNG
任何想法如何制作它,以便当我执行搜索特定用户时,我只获得该用户的所有20个结果,而下一页给出了NEXT 20个元素,没有显示我刚才看到的任何20个元素。
答案 0 :(得分:1)
使用以下代码进行分页。它是非常理想的代码,易于理解和实现。
服务器发布:
Meteor.publish('Students', function (str, toSkip, tillLimit) {
var regex = new RegExp(str, 'i');
var data = Students.find( {
$or:[
{"_id": {'$regex' : regex}},
{"username": {'$regex' : regex}}
]
},
{sort: {'time': -1}, skip: toSkip, limit : tillLimit});
return data;
});
Meteor.publish('StudentsTotalCount', function (str) {
var regex = new RegExp(str, 'i');
Counts.publish(this, "StudentsTotalCount", Students.find({
$or:[
{"_id": {'$regex' : regex}},
{"username": {'$regex' : regex}}
]
});
);
});
str
是来自客户端的全局搜索文本。现在,由于用户会经常点击next
和previous
按钮。在客户端,订阅必须是被动的。为此你可以在代码之下。
客户订阅:
在某个App_ShowStudents.js
文件中,您可以创建订阅,如下所示;
Template.App_ShowStudents.onCreated(function(){
this.userId = new ReactiveVar("");
this.filterCriteria = new ReactiveVar("");
//PAGINATION
this.enablePrevious = new ReactiveVar(false);
this.enableNext = new ReactiveVar(true);
this.skip = new ReactiveVar(0);
this.diff = new ReactiveVar(0);
this.total = new ReactiveVar(0);
this.limit = new ReactiveVar(10);
this.autorun(() => {
Meteor.subscribe('Students', this.filterCriteria.get(), this.skip.get(), this.limit.get());
Meteor.subscribe('StudentsTotalCount', this.filterCriteria.get(), this.role.get());
});
});
<强>助手:强>
Template.App_ShowStudents.helpers({
students(){
return Students.findOne({}); // this will always be less or equal to 10.
},
skip(){
return Template.instance().skip.get();
},
diff(){
var instance = Template.instance();
var add = instance.skip.get() + instance.limit.get();
var total = instance.total.get();
var diff = (add >= total ? total : add);
instance.diff.set(diff);
return instance.diff.get();
},
total(){
Template.instance().total.set(Counts.get('StudentsTotalCount'));
return Template.instance().total.get();
}
});
total
实际上必须是被动的,并且只应根据您的搜索条件给出计数,因此我们在服务器上进行单独发布。
<强>事件:强>
Template.App_ShowStudents.events({
'click .previous': function (event, template) {
event.preventDefault();
if(template.diff.get() > template.limit.get()){
template.skip.set(template.skip.get() - template.limit.get());
}
},
'click .next': function (event, template) {
event.preventDefault();
if(template.diff.get() < template.total.get()){
template.skip.set(template.skip.get() + template.limit.get());
}
},
'input #searchData': function( event, template ) {
if ( $( event.target ).val()) { // has some value.
template.filterCriteria.set( $( event.target ).val() );
} else {
template.filterCriteria.set( "" );
}
console.log(template.filterCriteria.get());
},
});
<强> App_ShowStudents.html 强>
<template name="App_ShowStudents">
{{#if Template.subscriptionsReady}}
<body>
<input type="text" id="searchData" class="form-control input-lg" placeholder="Search ID, Username" />
Showing {{skip}} - {{diff}} of {{total}}
{{#each students}}
...
{{/each}}
<ul>
<li><a href="#" role="button" class="previous">Previous</a></li>
<li><a href="#" role="button" class="next">Next</a></li>
</ul>
</body>
{{else}}
Please wait...
{{/if}}
</template>