0

Firebase / AngularFire を使用して Ionic アプリを構築しています。そして、私はトリッキーな状況に直面しています: ng-repeat のパフォーマンスをより最適化したいと考えています。そして、それを行う最良の方法は無限スクロールだと聞きました。AngularFire を使用して、サービス/ファクトリ (具体的には $firebaseArray) 内のすべてのデータを取得しました。

私はグーグルでこれを見つけました:http://firebase.github.io/firebase-util/#/toolbox/Paginate/example/ionic

質問 1: Firebase util ライブラリを使用した Ionic の例での無限スクロールは、サーバー側の無限スクロールですか、それともクライアント側ですか? このライブラリは、ここで言及されているように ng-repeat のパフォーマンスの問題に対処していますか: ( http://www.alexkras.com/11-tips-to-improve-angularjs-performance/ )

質問 2: 私の firebaseArray は実際には、距離と呼ばれる変数を動的に計算する orderBy が必要です。セキュリティ ルールで .indexOn ルールを引き続き使用して、クエリのパフォーマンスを向上させることはできますか? (最初は距離がfirebaseに保存されていないため、私には不可能に聞こえます)

ここに私のコードがあります: 私の工場: 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;
        },
     }

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);
            }
        }
    }

そして私の見解:

<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>

ご覧のとおり、firebaseArray オブジェクトを取得した後に、distance プロパティを追加しました。この距離は、ユーザーの現在のデバイスの位置に基づいて動的に計算されます。したがって、ng-repeat は、ユーザーの現在の場所に最も近いアイテムを表示します。距離は動的であるため、Firebase で事前に保存することはできないため、firebase ルールは機能しません。

質問 3: 動的な値で Firebase.util の無限スクロールを使用するにはどうすればよいですか? ここでは、「距離」プロパティのように?

firebase util のドキュメントを見たので、それを行う必要があります。

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

しかし、baseRef には距離がありません。firebaseArray がロードされた後に生成されました。では、これにどのようにアプローチすればよいでしょうか。

また、構造の観点から、scrollRef と firebaseArray の両方を自分のファクトリ (taskService.js) に配置します。

// スクロール可能な参照を作成します var scrollRef = new Firebase.util.Scroll(baseRef, 'distance');

// スコープで同期配列を作成します return $firebaseArray(scrollRef);

次に、ファクトリは $firebaseArray(scrollRef) のみを返すため、scrollRef.scroll.next(3); のようなドキュメントに記載されている scroll.next 関数にアクセスするにはどうすればよいですか? 私のコントローラーで?scrollRef オブジェクトがないので、FirebaseArray だけ...

4

1 に答える 1

5

Q1 に関して: firebase-util の Scroll は、スクロール時にクエリ パラメータを更新し、サーバーからの変更を同期することでスクロールを実装します。サーバーは、キャッシュとプリフェッチによって参加し、スクロールの更新を高速にします。

ng-repeat のパフォーマンスの問題は、ng-repeat が非常に多くの要素を処理できないことのようです。Scroll を使用すると、繰り返される要素の数を制限することで、この問題に対処できます。

Q2 に関して: ユーザーと表示したい要素の間の大円距離のインデックス作成は不可能になります。より良いアプローチは、ジオハッシュを使用することです。geofireライブラリはこれを firebaseに直接実装しているため、ユーザーの近くにあるものを簡単に見つけることができます。

Q3 に関して: GeoFire 自体が (半径を制限することによって) 結果を制限する手段を提供するため、この問題を解決する必要さえない可能性があります。固定数の要素に制限したい場合は、geofire クエリの結果を自分で後処理する必要があります。

于 2015-09-16T16:51:59.780 に答える