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