backbone-paginator/backbone-pageable

Unable to get infinite mode working

TimNZ opened this issue · 8 comments

I can't get this to work. Using it with backgrid, following your example code.

My PageableCollection.
Dummy parseLinks for testing.

  var PageableActivityCollection = PageableCollection.extend(
      {
          model: ActivityModel,
          mode: 'infinite',
          state: {
              pageSize: 20,
              sortKey: 'created_at',
              order: 1,
              firstPage: 1,
              currentPage: 1
          },
          initialize: function(options)
          {
              this.queryParams.link_id = options.link_id;
              this.queryParams.link_type = options.link_type;
          },
          queryParams: {
              totalPages: null,
              pageSize: 'ps',
              currentPage: 'page',
              sortKey: "s",
              order: "d",
              directions: {
                  "-1": "asc",
                  "1": "desc"
              }
          },
          url: '/data/activity',
          parseLinks: function (resp, xhr)
          {
              return {
                  first: '/data/activity/1',
                  next: '/data/activity/2',
              }
          }
      });
        this.collection = new PageableActivityCollection(
            {},
            { 
                mode: 'infinite',
                link_id: options.link_id,
                link_type: options.link_type
            });


         this.collection.getFirstPage().complete(function ()
        {
            self.$el.find('.box-body .table-container').append(pageableGrid.render().$el);
            self.$el.find('.box-body').append(footer.render().$el);
        });

It fails on this line in getPage()

if (mode == "infinite") options.url = self.links[pageNum];

The issue is links has no value yet, no data has been retrieved from the server.
No matter what way I do this links is always undefined yet code references it, no fetch is ever performed.

What am I doing wrong?

Well I am a javascript retard.

Of course I'm overriding initialize and not calling the super, and I got the wrong signature. Sigh...

 initialize: function(models,options)
          {
              this.queryParams.link_id = options.link_id;
              this.queryParams.link_type = options.link_type;
              PageableCollection.prototype.initialize.apply(this, options);
          },

Will close shortly I expect :)

Hmmm, now I'm stumped.

Line 426 in _makeCollectionEventHandler: pageCol.pop()

        if (colToAdd) {
            colToAdd.add(model, _extend({}, options || {}, {at: addAt}));
            pageCol.pop();
          }
        }

This ultimately results in a call to backgrid.Body.removeRow, which fails as there are no rows yet.

I don't know what to do from here.

I am creating an instance like this:

this.collection = new PageableActivityCollection(
            null,
            { 
                mode: 'infinite',
                link_id: options.link_id,
                link_type: options.link_type
            });

Mmm. I am not sure what's going on here, but fetching under infinite mode should not result in any add or remove events. They are explicitly suppressed with silent: true unless you pass in an options hash {silent: false} to any fetch methods. Fetching should simply trigger a reset event.

Also, you might want to move your prototype.initialize call up to be the first line of initialize. You are modifying Backbone.PageableCollection.prototype.queryParams. Backbone.PageableCollection.prototype.initialize makes a copy of it to the instance during initialization. You should modify that copy instead.

Wow, I spent hours on this today, insane waste of time.

The issue is I create the Backgrid instance passing in the PageableCollection before I call getFirstPage(), and subsequently there is some flaw in the logic with regards to the collection being subsequently populated.

If you change your example to create the grid outside of getFirstPage you'll hit the problem straight away.
Is that a bug or something that needs to be documented?

Seems like a bug inside the success handler. An undefined has overridden the silent: true set when calling update.

https://github.com/wyuenho/backbone-pageable/blob/master/lib/backbone-pageable.js#L1078

Yup, I noticed that in my many step throughs, but the same thing was happening with your example on your github page and it worked fine. Only diff between yours and mine is when I instantiate backgrid.

Thanks for the follow up. Great code, well designed.

Cool thanks for being so responsive.

I will do a fork for better handling paging for when there is no return data or less than expected.

The current page is changed even if the amount of returned rows would result in the pageSize of the current page not being exceeded, resulting in an empty grid being displayed.

👍