Material angular infinite scroll with $http request

后端 未结 3 1129
轮回少年
轮回少年 2021-01-05 17:20

I\'m using md-virtual-repeat directive of Angular Material to have an infinite scroll, and I need to replace it\'s demo $timeout function with a $h

3条回答
  •  广开言路
    2021-01-05 17:54

    came here and saw @alessandro-buggin answer which was very helpful. I had to change it a little bit, so I thought of sharing it for others to help. I needed:

    • to avoid getting scroll requests while already recovering data (using this.hold)
    • stopping requests when the whole data was received from the backend (using this.stop_)
    • hiding the content while loading, to avoid glitches or empty elements (again using this.hold). On the view you need to use ng-hide on that element because ng-if avoid the element to ever exist so it won't load the first time.
    • implementing a refresh method to reload data when parameters/filters changed from an outside form.

    Far from perfect but works pretty well.

    vm.elements = null;
    vm.infiniteItems = { // Start of infinte logic
    
    stop_: false,
    hold: false,
    numLoaded_: 0,
    toLoad_: 0,
    items: [],
    
    refresh: function() {
        this.stop_ = false;
        this.hold = false;
        this.numLoaded_ = 0;
        this.toLoad_ = 0;
        this.items = [];
    },
    
    getItemAtIndex: function (index) {
        if (!this.hold) {
            if (index > this.numLoaded_) {
                this.fetchMoreItems_(index);
                return null;
            }
        }
        return this.items[index];
    },
    
    getLength: function () {
        if (this.stop_) {
            return this.items.length;
        }
        return this.numLoaded_ + 5;
    },
    
    fetchMoreItems_: function (index) {
        if (this.toLoad_ < index) {
    
            this.hold = true;
            this.toLoad_ += 5;
    
            var start = this.numLoaded_;
            if (start > 0) start++;
    
            MyService.getData(parameters)
             .then(angular.bind(this, function (obj) {
    
              if (obj && obj.elements > 0) {
                vm.elements = obj.elements;
                this.items = this.items.concat(obj.data);
    
                if (obj.elements < this.toLoad_) {
                    this.stop_ = true;
                }
                this.numLoaded_ = this.items.length;
                this.hold = false;
    
              } else { // if no data
                vm.elements = 0;
              }
            }));
        }
    }
    
    } // End of infinte logic
    

    Note: my service returns an object composed like this: obj = {elements: INTEGER, data: ARRAY} where elements tells you the length of the full query.

提交回复
热议问题