AngularFire服务器端无限滚动,带有距离计算顺序.

Hug*_*Hou 0 infinite-scroll firebase angularjs-ng-repeat firebase-util

我正在使用Firebase/AngularFire构建一个Ionic App.我面临着一个棘手的问题:我希望我的ng-repeat能够更好地进行性能优化.我听说最好的方法就是无限滚动.我使用AngularFire在服务/工厂中获取所有数据 - 更具体地说,$ firebaseArray.

我谷歌发现了这个:http://firebase.github.io/firebase-util/#/toolbox/Paginate/example/ionic

问题1:使用Firebase util库的无限滚动是无限滚动服务器端无限滚动还是客户端?这个库是否解决了ng-repeat的性能问题,如下所述:(http://www.alexkras.com/11-tips-to-improve-angularjs-performance/)

问题2:我的firebaseArray实际上需要命令动态计算一个名为distance的变量.我是否仍可以在安全规则中使用.indexOn规则来提高查询性能?(声音不可能,因为距离最初没有存放在火场中)

这是我的代码:我的工厂: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;
        },
     }
Run Code Online (Sandbox Code Playgroud)

我的ng-repeat视图控制器:

    $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);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

我的观点是:

<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>
Run Code Online (Sandbox Code Playgroud)

如您所见,我在获取firebaseArray对象后添加了distance属性.并且该距离是基于用户当前设备​​位置动态计算的.因此ng-repeat将显示最接近用户当前位置的项目.由于距离是动态的,我无法在我的Firebase中保存它,因此firebase规则将无效.

问题3:如何在动态值上使用Firebase.util无限滚动 - 如此处的"距离"属性?

当我看到firebase util的文档时,我需要这样做:

   // create a scrollable reference
  var scrollRef = new Firebase.util.Scroll(baseRef, 'distance');
Run Code Online (Sandbox Code Playgroud)

但是baseRef中没有距离.它在firebaseArray加载后生成.那我该怎么做呢?

另外,从结构的角度来看,我会将scrollRef和firebaseArray放在我的工厂中 - taskService.js

//创建一个可滚动的引用var scrollRef = new Firebase.util.Scroll(baseRef,'distance');

//在范围上创建一个synchronized数组返回$ firebaseArray(scrollRef);

然后,由于工厂只返回$ firebaseArray(scrollRef),我如何访问文档中所述的scroll.next函数,如scrollRef.scroll.next(3); 在我的控制器?由于我没有scrollRef对象,只有FirebaseArray ......

Sar*_*ara 5

Re Q1:firebase-util的Scroll通过更新查询参数并在滚动时同步服务器的更改来实现滚动.服务器通过缓存和预取来参与以快速进行滚动更新.

ng-repeat性能问题似乎是ng-repeat不能处理非常多的元素.使用Scroll可以通过限制重复元素的数量来解决这个问题.

问题Q2:索引用户与要显示的元素之间的大圆距离是不可能的.更好的方法可能是使用geohashing.该geofire库直接火力实现这一点,因此很容易找到的东西在附近的用户.

问题3:GeoFire本身提供了限制结果的方法(通过限制半径),因此您可能甚至不必解决此问题.如果您想限制为固定数量的元素,则需要为自己对地理空间查询的结果进行后处理.