所以我使用GeoFire和AngularFire来填充我的重复项目列表。有一个离子拉刷新列表。因此,用户拉它并获得当前更新的位置并刷新列表(召回GeoFire以重新填充列表)。
$scope.doRefresh = function() {
if ($scope.doneLoading) {
$scope.useCurrentLocation().then(function() {
$scope.userCurrentLocation = {
lat: geoLocation.getGeolocation().lat,
lng: geoLocation.getGeolocation().lng
}
angular.forEach($scope.tasks, function(child) {
child.$destroy();
});
setupTaskListing();
$scope.$broadcast('scroll.refreshComplete');
})
}
}
function setupTaskListing() {
console.log("setupTask is being called");
if ($scope.tasks.length > 0) {
console.log("task is not empty!");
$scope.tasks = [];
}
if ($scope.query) {
console.log("$scope.query is not empty:" + $scope.query);
$scope.query.cancel();
}
var radiusInMiles = ($scope.radius) * 1.60934;
$scope.query = taskService.setGeoQuery($scope.userCurrentLocation.lat, $scope.userCurrentLocation.lng, radiusInMiles); //My service to set Geo Query.
var geoQueryCallback = $scope.query.on("key_entered", "SEARCH:KEY_ENTERED");
}
$scope.$on("SEARCH:KEY_ENTERED", function(event, key, location, distance) {
//my service to get a single task. It return a firebase object. So I use $loaded
var task = taskService.getTask(key);
task.$loaded().then(function(data) {
data.distance = parseInt(distance * 0.621371192);
data.id = data.$id;
$scope.tasks.push(data);
});
});
如您所见,上面的代码非常简单。doRefresh()调用setupTaskListing()。它设置了geoQueryCallback,当key enter事件触发时,将新数据推入$作用域。任务数组。所以这是可行的。但是这个GeoFire结构的问题是…我不知道什么时候所有的任务都完成了进入半径…因此,当半径内没有数据时,我无法设置加载器和提示。当没有数据输入时,key_entered事件永远不会触发,所以我永远不会知道是否有数据。它可以是没有数据或GeoFire仍在加载。如果我把loader.hide()方法放在$scope中。$on,当实际没有数据时,它将永远不会触发。所以我的屏幕会一直加载。理想的用户体验应该是停止加载并提示人们增加搜索半径。如果我把loader.hide()放在$作用域之外。使用set $timeout来调用它。在$timeout运行之前,GeoFire需要更长的时间来加载数据。因此,用户将提示更改半径屏幕,然后闪回实际列表。糟糕的用户体验。所以…我有什么选择?我可以在GeoFire中使用某种承诺吗?
Geofire在以下情况触发"Query Ready"事件:
所有当前数据已从服务器加载,所有初始事件已触发。
请参阅Geofire文档的这一部分。
代码示例:
var onReadyRegistration = geoQuery.on("ready", function() { console.log("GeoQuery has loaded and fired all other events for initial data"); });