I am building an Ionic App with Firebase / AngularFire. And I am facing a tricky situation: I want my ng-repeat to be more performance optimized. And I heard the BEST way to do it is infinite scroll. I used AngularFire to get all my data in a service/factory - more specifically, $firebaseArray.
I google and found this: http://firebase.github.io/firebase-util/#/toolbox/Paginate/example/ionic
Question 1: is the infinite scroll with Ionic example using Firebase util library a server side infinite scrolling or a client side? Does this library address the performance issue of ng-repeat like mentioned here: (http://www.alexkras.com/11-tips-to-improve-angularjs-performance/)
Question 2: my firebaseArray actually need to orderBy a dynamically calculate variable called distance. Can I still use .indexOn rule in my Security Rules to improve query performance? (sound impossible to me since the distance is not stored in firebase at first)
Here is my code: My factory: taskService.js
var ref = new Firebase(FirebaseUrl);
var tasks = $firebaseArray(ref.child('tasks'));
var Task = {
all: tasks,
getAllTasks: function() {
if (tasks.length == 0) {
tasks = $firebaseArray(ref.child('tasks'));
} else {
tasks = tasks;
}
return tasks;
},
}
My controller for the ng-repeat view:
$scope.tasks = taskService.getAllTasks();
$scope.tasks.$loaded().then(function(data){
calculateDistance($scope.tasks, $scope.userCurrentLocation);
});
var unwatch = $scope.tasks.$watch(function(event) {
calculateDistance($scope.tasks, $scope.userCurrentLocation);
});
$scope.$on('$ionicView.leave', function(){
// Anything you can think of
unwatch();
});
}
//--------------GeoLocation Calculation
var calculateDistance = function (tasks, userCurrentLocationData) {
for (var id in tasks) {
var task = tasks[id];
if (task.addressLat) {
var taskLocation = new google.maps.LatLng(task.addressLat, task.addressLng);
var userCurrentLocation = new google.maps.LatLng(userCurrentLocationData.lat, userCurrentLocationData.lng);
var distance = google.maps.geometry.spherical.computeDistanceBetween(userCurrentLocation, taskLocation);
$scope.tasks[id].distance = parseInt(distance*0.000621371192);
}
}
}
And my view:
<a class="item item-avatar" ng-repeat="task in tasks | filter: searchTask | orderBy: ['-status', 'distance', '-datetime'] track by task.$id" ng-href="#/app/task/{{task.$id}}">
....
</a>
As you see here, I added the distance property after I get the firebaseArray object. And this distance is calculated dynamically based on user current device location. So the ng-repeat will show item closest to user current location. As distance is dynamic, I can not save it before hand in my Firebase so the firebase rule won't work.
Question 3: How can I use Firebase.util infinite scroll on a dynamic value - as in here, the "distance" property?
As I saw the doc of firebase util, I will need to do that:
// create a scrollable reference
var scrollRef = new Firebase.util.Scroll(baseRef, 'distance');
But distance is not there in the baseRef. It generated after the firebaseArray loaded. So how should I approach this?
Also, from a structure stand point, I will put both the scrollRef and the firebaseArray in my factory - taskService.js
// create a scrollable reference var scrollRef = new Firebase.util.Scroll(baseRef, 'distance');
// create a synchronized array on scope return $firebaseArray(scrollRef);
Then, since the factory return just the $firebaseArray(scrollRef), how do I get access into scroll.next function stated in the doc like scrollRef.scroll.next(3); in my controller? Since I do not have the scrollRef object, just the FirebaseArray...