0

ユーザーが写真を並べ替えたり、ユーザーごとにフィルター処理したり、興味のある複数のカテゴリをチェックしたり、フィルター処理されたデータを日付やお気に入りの数などで並べ替えたりできるインタラクティブな写真データベースを作成しようとしています。フィルター/並べ替え条件は DOM でユーザーによって選択され、クライアント側から に保存されます$scope.model。ユーザーに表示されるデータの量は、無限スクロールで制御されます。

この例のリポジトリを作成し、ここにデプロイしましたscroll.controller.js以下から関連するコードの一部を再現しました。

コード

// infinite-scroll logic & collection subscription //
$scope.currentPage = 1;
$scope.perPage = 12;
$scope.orderProperty = '-1';
$scope.query = {};

$scope.images = $scope.$meteorCollection(function() {
  query={};            
  // if filtered by a user...
  if ($scope.getReactively('model.shotBy')) {
    query.shotBy = $scope.model.shotBy;
  };
  // if category filter(s) are selected...
  if ($scope.getReactively('model.category', true)) {
    if ($scope.model.category.length > 0){
      var categories = [];
      for (var i=0; i < $scope.model.category.length; i++){            
        categories.push($scope.model.category[i]);
      }
      query.category = {$in: categories};
    }
  };
  $scope.currentPage = 1; // reset
  return Images.find(query, { sort: $scope.getReactively('model.sort')});
});

$meteor.autorun($scope, function() {
  if ($scope.getReactively('images')){
    $scope.$emit('list:filtered');    
  }
});

$meteor.autorun($scope, function() {
  $scope.$meteorSubscribe('images', {
    limit: parseInt($scope.getReactively('perPage'))*parseInt(($scope.getReactively('currentPage'))),
    skip: 0,
    sort: $scope.getReactively('model.sort')
  });
});              

$scope.loadMore = function() {
  // console.log('loading more');
  $scope.currentPage += 1;
};  

問題

画像をうまくスクロールでき、無限スクロール機能も機能しているようです。ただし、DOM から画像をフィルタリングしようとすると、フィルタリングされた結果はスクロール前に最初に表示されたものだけであり、$scope.$emit を使用しているにもかかわらず、スクロールしても基準を満たす残りの画像は表示されません。さらに読み込むように ngInfiniteScroll に通知します ( documentation )。

EDIT:最初のフィルタリングされたリスト実際に一番下に到達した場合、スクロールは適切に追加されます。最初のフィルタリングされたリストがスクリーンの一番下に達しない場合にのみ追加されないようです。

質問

フィルタリングされたコレクションで期待どおりに ngInfiniteScroll を動作させるには、何を変更できますか?

ヘルプ、考え、または提案をいただければ幸いです。他に見たいものがあればお知らせください。ありがとうございました!

4

1 に答える 1

0

まあ、理解するのにほぼ一日かかりましたが、現在、この Github リポジトリに実用的な例があり、ここにデプロイされています。

要約すると、適切に適用され、ngInfiniteScroll が機能するには、コレクション レベルとサブスクリプション レベルの両方でフィルター処理する必要があることがわかりました。perPageまた、$scope.$emit画像配列が小さすぎて画面の端に達しなかった場合に備えて、ngInfiniteScroll 経由でイベントを送信して、再度起動するように指示する必要がありました。興味のある方は、Github レポジトリで詳細を確認してください。

関連するコードを更新しました

// infinite-scroll logic & collection subscription //
$scope.currentPage = 1;
$scope.perPage = 12;
$scope.query = {};

function getQuery(){
  query={};            
  // if filtered by a user...
  if ($scope.getReactively('model.shotBy')) {
    query.shotBy = $scope.model.shotBy;
  };
  // if category filter(s) are selected...
  if ($scope.getReactively('model.category', true)) {
    if ($scope.model.category.length > 0){
      var categories = [];
      for (var i=0; i < $scope.model.category.length; i++){            
        categories.push($scope.model.category[i]);
      }
      query.category = {$in: categories};
    }
  };
  return query;
}

$meteor.autorun($scope, function(){
  $scope.images = $scope.$meteorCollection(function() {
    $scope.currentPage = 1; // reset the length of returned images
    return Images.find(getQuery(), { sort: $scope.getReactively('model.sort')});
  });
  $scope.$emit('filtered'); // trigger infinite-scroll to load in case the height is too small 
});

$meteor.autorun($scope, function() {
  $scope.$meteorSubscribe('images', {
    limit: parseInt($scope.getReactively('perPage'))*parseInt(($scope.getReactively('currentPage'))),
    skip: 0,
    sort: $scope.getReactively('model.sort'),
    query: getQuery()
  });
});              

$scope.loadMore = function() {
  // console.log('loading more');
  $scope.currentPage += 1;
};         

この回答でベストプラクティスを使用したかどうかはわかりませんので、お気軽に提案をお寄せください.

于 2015-11-11T05:38:06.640 に答える