我什么时候知道 GeoFire 已完成加载,因为它是基于事件的触发器 [英] When do I know GeoFire is finished loading as it is Event based trigger

查看:22
本文介绍了我什么时候知道 GeoFire 已完成加载,因为它是基于事件的触发器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我使用 GeoFire 和 AngularFire 来填充我的 ng-repeat 项目列表.有一个离子拉来刷新列表.所以用户拉它并获取当前更新的位置并刷新列表(调用 GeoFire 重新填充列表).

$scope.doRefresh = function() {如果($scope.doneLoading){$scope.useCurrentLocation().then(function() {$scope.userCurrentLocation = {纬度:geoLocation.getGeolocation().lat,lng: geoLocation.getGeolocation().lng}angular.forEach($scope.tasks, function(child) {child.$destroy();});设置任务列表();$scope.$broadcast('scroll.refreshComplete');})}}函数 setupTaskListing() {console.log("setupTask 正在被调用");如果($scope.tasks.length > 0){console.log("任务不为空!");$scope.tasks = [];}如果($scope.query){console.log("$scope.query 不为空:" + $scope.query);$scope.query.cancel();}var radiusInMiles = ($scope.radius) * 1.60934;$scope.query = taskService.setGeoQuery($scope.userCurrentLocation.lat, $scope.userCurrentLocation.lng, radiusInMiles);//我的服务设置地理查询.var geoQueryCallback = $scope.query.on("key_entered", "SEARCH:KEY_ENTERED");}$scope.$on("SEARCH:KEY_ENTERED", function(event, key, location, distance) {//我的服务来获取单个任务.它返回一个 firebase 对象.所以我使用 $loadedvar 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,当键输入事件触发时,将新数据推送到 $scope.tasks 数组中.所以它有效.

但是这个 GeoFire 结构的问题是......我不知道所有任务何时完成进入半径......所以我无法设置加载器并在半径内没有数据时提示.当没有数据输入时,key_entered 事件永远不会触发,所以我永远不会知道是否有数据.它可以是 NO 数据或 GeoFire 仍在加载.如果我将 loader.hide() 方法放在 $scope.$on 中,当实际上没有数据时它永远不会触发.所以我的屏幕将永远加载.理想的用户体验应该是停止加载并提示人们增加搜索半径.如果我将 loader.hide() 放在 $scope.$on 之外并设置 $timeout 来调用它.GeoFire 在 $timeout 运行之前需要更长的时间来加载数据.所以用户会提示更改半径屏幕然后闪回实际列表.又是糟糕的用户体验.那么......我在这里的选择是什么?我可以在 GeoFire 中使用某种承诺吗?

解决方案

Geofire 在以下情况下触发查询就绪"事件:

<块引用>

所有当前数据已从服务器加载,所有初始事件均已触发.

请参阅Geofire 文档的这一部分.

那里的代码示例:

<块引用>

var onReadyRegistration = geoQuery.on("ready", function() {console.log("GeoQuery 已经加载并触发了初始数据的所有其他事件");});

So I used GeoFire and AngularFire for populate my ng-repeat item lists. There is an ionic pull to refresh list. So user pull it and get the current updated location and refresh the list (recall the GeoFire to re-populate the list).

$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);
  });
});

As you see the code above, pretty straight forward. doRefresh() call setupTaskListing(). And it setup geoQueryCallback that when key entered event fire, push new data into the $scope.tasks array. So it works.

But the problem for this GeoFire structure is...I have no idea when ALL the tasks finished entering the radius...So I can not set up a loader and prompt when there is NO data inside the radius. When there is NO data enter, the key_entered event never fire, so I will never know if there is data or not. It can be either NO data or GeoFire still loading. If I put the loader.hide() method inside $scope.$on, it will never fire when there is actually no data. So my screen will forever loading. The ideal UX should be stop loading and prompt people to increase the search radius. If I put the loader.hide() outside the $scope.$on with a set $timeout to call it. GeoFire take longer to load the data before $timeout run. So user will prompt the change radius screen then flash back to the actual list. Bad UX again. So...what is my option here? Is there some kind of promise I can use in GeoFire?

解决方案

Geofire fires a "Query Ready" event when:

All current data has been loaded from the server and all initial events have been fired.

See this section of the Geofire documentation.

The code sample from there:

var onReadyRegistration = geoQuery.on("ready", function() {
  console.log("GeoQuery has loaded and fired all other events for initial data");
});

这篇关于我什么时候知道 GeoFire 已完成加载,因为它是基于事件的触发器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆