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
This one works:
plnkr
obj.data
, not plain obj
(function () {
'use strict';
angular.module('infiniteScrolling', ['ngMaterial'])
.controller('AppCtrl', function ($scope, $http) {
// In this example, we set up our model using a plain object.
// Using a class works too. All that matters is that we implement
// getItemAtIndex and getLength.
var vm = this;
vm.infiniteItems = {
numLoaded_: 0,
toLoad_: 0,
items: [],
// Required.
getItemAtIndex: function (index) {
if (index > this.numLoaded_) {
this.fetchMoreItems_(index);
return null;
}
return this.items[index];
},
// Required.
getLength: function () {
return this.numLoaded_ + 5;
},
fetchMoreItems_: function (index) {
if (this.toLoad_ < index) {
this.toLoad_ += 5;
$http.get('items.json').then(angular.bind(this, function (obj) {
this.items = this.items.concat(obj.data);
this.numLoaded_ = this.toLoad_;
}));
}
}
}
})
})();
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:
this.hold
)this.stop_
)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.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.
On every api call try to get wheather the db has few more records or not. and add that condition in fetchMoreItems_ function.
fetchMoreItems_: function (index) {
if (this.toLoad_ < index && hasMoreRecords) {
this.toLoad_ += 5;
In our code we get the details like