使用 infinite-scroll 支持过滤 angular-meteor collection 时出现问题
Trouble filtering angular-meteor collection with infinite-scroll support
我正在尝试创建一个交互式照片数据库,用户可以在其中对照片进行排序并按用户进行过滤,检查他或她感兴趣的多个类别,并按日期、收藏数量等对过滤后的数据进行排序. filter/sorting 条件由用户在DOM 上选择并从客户端存储到$scope.model
。用户可见的数据量将通过无限滚动来控制。
我创建了一个 repository of this example, and I've deployed it here。我从下面的 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;
};
问题
我可以很好地滚动浏览图像,而且 infinite-scroll 功能似乎有效。但是,当我尝试从 DOM 中过滤图像时,唯一过滤的结果是那些在滚动之前最初可见的结果,并且滚动不会使其余符合条件的图像显示,尽管使用 $ scope.$emit 向 ngInfiniteScroll 发出信号以加载更多 (documentation)。
编辑:如果初始过滤列表确实,实际上到达底部,滚动将正确附加。它似乎只有在初始过滤列表没有到达屏幕底部时才追加。
问题
我可以更改什么以使 ngInfiniteScroll 在过滤 collection 上表现得像我期望的那样?
如有任何帮助、想法或建议,我们将不胜感激,如果您还有其他想要了解的内容,请告诉我。谢谢!
好吧,我花了几乎一整天的时间才弄清楚,但我现在在 this Github repository and deployed here 有一个工作示例。
总而言之,我发现我需要在 收集和订阅级别进行过滤,以使 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;
};
我不确定我是否使用了这个答案的最佳实践,所以请随时提出建议。
我正在尝试创建一个交互式照片数据库,用户可以在其中对照片进行排序并按用户进行过滤,检查他或她感兴趣的多个类别,并按日期、收藏数量等对过滤后的数据进行排序. filter/sorting 条件由用户在DOM 上选择并从客户端存储到$scope.model
。用户可见的数据量将通过无限滚动来控制。
我创建了一个 repository of this example, and I've deployed it here。我从下面的 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;
};
问题
我可以很好地滚动浏览图像,而且 infinite-scroll 功能似乎有效。但是,当我尝试从 DOM 中过滤图像时,唯一过滤的结果是那些在滚动之前最初可见的结果,并且滚动不会使其余符合条件的图像显示,尽管使用 $ scope.$emit 向 ngInfiniteScroll 发出信号以加载更多 (documentation)。
编辑:如果初始过滤列表确实,实际上到达底部,滚动将正确附加。它似乎只有在初始过滤列表没有到达屏幕底部时才追加。
问题
我可以更改什么以使 ngInfiniteScroll 在过滤 collection 上表现得像我期望的那样?
如有任何帮助、想法或建议,我们将不胜感激,如果您还有其他想要了解的内容,请告诉我。谢谢!
好吧,我花了几乎一整天的时间才弄清楚,但我现在在 this Github repository and deployed here 有一个工作示例。
总而言之,我发现我需要在 收集和订阅级别进行过滤,以使 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;
};
我不确定我是否使用了这个答案的最佳实践,所以请随时提出建议。