流星分页问题 [英] Meteor Pagination Issue

查看:147
本文介绍了流星分页问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了我实施的分页问题。分页工作基于服务器端发布跳过&限制过滤器。

问题#1。
如果我执行特定的用户搜索,第一页将是空白的。



再次提供甚至更多 results



并最终无法访问数据,转到下一页 10条结果,显示10条



这是一个很奇怪的行为。
服务器端发布

  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')|| (创建时间:默认限制),排序:{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(客户端)



https://pastebin.com/tWakPDT1



main.html
https://pastebin.com/4uMVFsNG



任何想法如何当我执行搜索某个特定用户时,我会为该用户获得全部20个结果,而下一页给出了我下一个20个元素,而不是显示我刚才看到的20个结果。

解决方案

使用下面的代码进行分页。这是非常理想的代码,易于理解和实施。



SERVER PUBLISH:



< pre $ Meteor.publish('Students',function(str,toSkip,tillLimit){
var regex = new RegExp(str,'i');
var data = Students.find({
$或:[
{_id:{'$ regex':regex}},
{username:{'$ regex':regex }}
$ b $,b $ b {sort:{'time':-1},skip:toSkip,limit:tillLimit});
返回数据;
});
$ b Meteor.publish('StudentsTotalCount',function(str){
var regex = new RegExp(str,'i');
Counts.publish(this,StudentsTotalCount ,Students.find({
$或:[
{_id:{'$ regex':regex}},
{username:{'$ regex':regex }}
]
});
);
});

str 是客户端的全局搜索文本。现在,由于用户会经常点击下一个以前的按钮。在客户端,订阅必须是被动的。为此,你可以在下面的代码。



客户订阅

App_ShowStudents.js 文件,您可以按如下方式创建订阅;

 模板.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());
});
});

HELPERS:

  Template.App_ShowStudents.helpers({
students(){
return Students.findOne({}); //这将始终小于或等于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();
}
});

总共实际上必须是反应性的,只计算您的搜索条件,因此我们在服务器上进行了单独发布。



活动:

  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()){//有一些值
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 =textid =searchDataclass =form-control input-lgplaceholder =Search ID,Username/>
显示{{total}}
{{#每个学生}}
...
{{/每个}}的{{skip}} - {{diff}}}
< ul>
< li>< a href =#role =buttonclass =previous>上一页< / a>< / li>
< li>< a href =#role =buttonclass =next> Next< / a>< / li>
< / ul>
< / body>
{{else}}
请等待...
{{/ if}}
< / template>


I am having issues with pagination I've implemented. Pagination works based on server-sided publish skip & limit filter.

Issue #1. If I perform a specific user search the very first page will be blank.

At that state skip is set to 0, limit is always 20.

If I perform a find().fetch() I get 20 elements, but they are all for a different user.

Issue #2 Me going to next page (skip+10) gives me a few more elements

Doing it again gives even more results

and finally being out of data, and going to next page just removes 10 results, leaving 10 shown

This is a very odd behavior. Server-sided publish

Meteor.publish('overtime', function(opt){
if (!Roles.userIsInRole(this.userId, 'admin')) {
return Overtime.find({userId: this.userId}, opt);
} else {
return Overtime.find({}, opt);
}
});

Client-sided subscription

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}});
});

Next page click event

"click .nxtpage_over": function(event, template){
Session.set('overSkip', (Session.get('overSkip') || 0) + defaultSkipStep);
Session.set('limit', 20);
},

Submit event https://pastebin.com/btYCSQBD

Query that user sees main.js (client)

https://pastebin.com/tWakPDT1

main.html https://pastebin.com/4uMVFsNG

Any idea how to make it so that when I perform search for a specific user I get all 20 results just for that user, and next page gives me NEXT 20 elements, not showing any one the 20 I've just seen.

解决方案

Use below code for pagination. It is very ideal code, easy to understand and implement.

SERVER PUBLISH:

        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 is global search text from client side. Now, Since the user will click on next and previous button frequently. On the client side the Subscription must be reactive. For that you can you below code.

CLIENT SUBSCRIBE:

Inside some App_ShowStudents.js file, you can create subscription as below;

    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());
      });
    }); 

HELPERS:

    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 actually must be reactive and should give only count as per your search criteria, so we had a seperate publish on server.

EVENTS:

    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>

这篇关于流星分页问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆