javascript - Meteor 分页问题

标签 javascript html meteor pagination

我在实现分页时遇到问题。分页基于服务器端发布跳过和限制过滤器工作。

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

当状态跳过设置为 0 时,限制始终为 20。

如果我执行 find().fetch() 我会得到 20 个元素,但它们都是针对不同的用户的。 enter image description here

问题 #2 我转到下一页 (skip+10) 会显示更多元素 enter image description here

再做一次会得到更多结果 enter image description here

最后数据耗尽,转到下一页仅删除 10 个结果,仅显示 10 个 enter image description here

这是一种非常奇怪的行为。 服务器端发布

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(客户端)

https://pastebin.com/tWakPDT1

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

知道如何做到这一点,以便当我执行对特定用户的搜索时,我仅获得该用户的所有 20 个结果,并且下一页为我提供了下 20 个元素,而不显示我刚刚看到的 20 个元素。

最佳答案

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

服务器发布:

        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 是来自客户端的全局搜索文本。现在,由于用户会频繁点击下一个上一个按钮。在客户端,订阅必须是响应式的。为此,您可以使用下面的代码。

客户订阅:

在一些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 实际上必须是 react 性的,并且应该只根据您的搜索条件给出计数,因此我们在服务器上进行了单独的发布。

事件:

    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>

关于javascript - Meteor 分页问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45458125/

相关文章:

html - 为带有背景图像的 <select> 设置默认选项

javascript - nouislider 在某些事件中移动时消失

javascript - 在 Highstock 中重置/设置 ZoomType 控件

javascript - 删除mongodb中的数组元素

html - 如何制作不同尺寸的 table

javascript - MeteorJS 用户帐户 :core and meteor-roles

javascript - 表单值未插入 Meteor 应用程序中

javascript - Ajax 出错,每页显示 3 个用户

javascript - 使用 Restangular 使用 RESTful api - RESTful api 将数组作为顶级对象返回是否安全?

HTML 下拉多列