2014-10-17 29 views
2

我正在嘗試打印顯示其名稱以及其與用戶位置之間距離的對象列表。我通過GET檢索數據並根據緯度和經度計算距離。然而,我的範圍數組的長度仍然爲0.我想我的回調架構有問題,但我似乎無法弄清楚。AngularJS:回調定義正確嗎?

控制器:

angular.module('ionicApp', ['ionic']).controller('objectCtrl', function($scope, $http) { 
$scope.objects = []; 
$http.get('http://url.com/getobjects.php').then(function (resp) { 
    for (var i = 0; i < resp.data.length; i++) { 
     getDistance(resp.data[i].lat, resp.data[i].lng, (function(index){ 
      return function(dist){ 
       $scope.objects[index] = { 
        name: resp.data[index].name, 
        distance: dist 
       }; 
      } 
     })(i)); 
    } 
}, function (err) { 
    console.error('ERR', err); 
    alert("error"); 
}); 

getDistance的:

function getDistance(lat2, lon2, callback) { 
    navigator.geolocation.getCurrentPosition(function onSuccess(position) { 
     var lat1 = position.coords.latitude; 
     var lon1 = position.coords.longitude; 
     var radlat1 = Math.PI * lat1/180; 
     var radlat2 = Math.PI * lat2/180; 
     var radlon1 = Math.PI * lon1/180; 
     var radlon2 = Math.PI * lon2/180; 
     var theta = lon1 - lon2; 
     var radtheta = Math.PI * theta/180; 
     var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta); 
     dist = Math.acos(dist); 
     dist = dist * 180/Math.PI; 
     dist = dist * 60 * 1.1515; 
     dist = dist * 1.609344; 
     callback(dist); 
    }, function onError(error) { 
     alert("no location found:"+ error); 
    }); 
} 

任何想法有什麼錯我的代碼?謝謝。

回答

1

看起來像getDistance回調出現在$摘要循環之外。所以,你應該嘗試手動啓動它:

$scope.objects[index] = { 
    name: resp.data[index].name, 
    distance: dist 
}; 
$scope.$apply(); 

或使用$timeout服務:

getDistance(resp.data[i].lat, resp.data[i].lng, (function (index) { 
    return function (dist) { 
     $timeout(function() { 
      $scope.objects[index] = { 
       name: resp.data[index].name, 
       distance: dist 
      }; 
     }); 
    } 
})(i)); 
+0

其中的2之一是「更好」的方式?我現在已經實現了第一個(效果很好),因爲我想我可以避免附加的函數定義。我的假設是否正確?非常感謝! – Tom 2014-10-17 12:12:36

+0

第二個更可靠,因爲它不會嘗試運行摘要,直到完成前一個摘要。所以不會有「$ digest已在進行中」的錯誤。 – dfsq 2014-10-17 12:14:11

+1

請不要使用'$ apply',這很少是一個好習慣。只需用'$ q'承諾包裝'navigator.geolocation.getCurrentPosition'並且不需要$ apply/$ timeout。 – Yoshi 2014-10-17 12:15:48

0

而不是

 $scope.objects[index] = { 
      name: resp.data[index].name, 
      distance: dist 
     }; 

更換

 $scope.objects.push({ 
      name: resp.data[index].name, 
      distance: dist 
     });