Фильтрация ошибок углового метеорного сбора с поддержкой бесконечной прокрутки

Я пытаюсь создать интерактивную базу данных фотографий, где пользователь может сортировать фотографии и фильтровать по пользователю, проверять несколько категорий, которые ему интересны, и сортировать отфильтрованные данные по дате, количеству избранных и т. Д. Фильтр / сортировка критерии выбираются пользователем в 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, чтобы загрузить больше ( документация).

РЕДАКТИРОВАТЬ: Если первоначальный отфильтрованный список действительно достигает дна, прокрутка добавится правильно. Кажется, он не добавляется, только если начальный отфильтрованный список не достигает нижней части экрана.

Вопрос

Что я могу изменить, чтобы ngInfiniteScroll вел себя так, как я ожидал отфильтрованной коллекции?

Буду признателен за любую помощь, мысли или предложения, и дайте мне знать, если вы хотите что-то еще увидеть. Спасибо!

1 ответ

Решение

Что ж, потребовалось почти весь день, чтобы выяснить это, но теперь у меня есть рабочий пример в этом хранилище Github, и он размещен здесь.

Подводя итог, я обнаружил, что мне нужно фильтровать как на уровне сбора и подписки, чтобы вызвать perPage правильно применять и для функционирования ngInfiniteScroll. Кроме того, мне нужно было отправить событие через $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;
};         

Я не уверен, использовал ли я лучшие практики с этим ответом, поэтому, пожалуйста, не стесняйтесь вносить предложения.

Другие вопросы по тегам