我正在尝试使用Forecast.io天气API来构建具有Ionic的天气应用程序。我有一段时间将AJAX响应数据发送到我的控制器,以便在我的视图中使用。
我的工厂服务:
.factory('WeatherService', function($cordovaGeolocation) {
var posOptions = { timeout: 10000, enableHighAccuracy: false };
return {
// Get current Geolocation position with the configured /posOptions/
getPosition : $cordovaGeolocation.getCurrentPosition(posOptions),
// Query the result of /getPosition/ for /lat/, /long/, and /accuracy/
getCoords : function(pos) {
var loc = {
lat : pos.coords.latitude,
long : pos.coords.longitude,
accuracy : pos.coords.accuracy
};
return loc;
},
// Build the API request URI
getApi : function(lat, long) {
var url = 'https://api.forecast.io/forecast/';
var apiKey = 'foo';
var forecastApi = url + apiKey + '/' + lat + ',' + long + '?callback=?';
return forecastApi;
},
// Execute a request against the API URI to recieve forecast data
getForecast : function(api) {
var forecast;
$.ajax({
url : api,
dataType : 'json',
async : false,
success : function(res) {
forecast = res;
}
});
return forecast;
}
};
})
我的控制器方法:
.controller('DashCtrl', function($scope, WeatherService) {
WeatherService.getPosition.then(function(pos) {
var pos = pos;
return pos;
}).then(function(pos) {
var coords = WeatherService.getCoords(pos);
return coords;
}).then(function(coords) {
var api = WeatherService.getApi(coords.lat, coords.long);
return api;
}).then(function(api) {
$scope.forecast = WeatherService.getForecast(api);
console.log($scope.forecast);
});
})
上面的代码可能存在许多本质上错误的东西。从我的阅读中我已经意识到,then()
方法确实不应该在控制器方法中使用,并且所有逻辑都应该与服务方法隔离。当我开始工作时,我将重构这种模式。
我正在使用jQuery $.ajax()
而不是$http
,因为在本地开发时,Forecast.io存在CORS问题。 $jsonp
在响应中抛出了语法错误,所以我不得不求助于jQuery来调用它以使其在本地运行。
我知道我收到了成功的回复,因为如果我在console.log(forecast)
电话中$.ajax
我可以浏览天气数据。无论出于何种原因,我无法将响应值保存到ajax调用的父作用域中保存的forecast
var,然后将其返回给控制器,以便在我的视图中使用$scope.forecast
变量。它始终返回undefined
。
我试图让自己开始工作时已经看了很多SO问题,并且还没有取得任何成功..
How do I return the response from an asynchronous call?
Get Data from a callback and save it to a variable in AngularJS
答案 0 :(得分:1)
好吧,如果你真的觉得需要使用ajax(可能更好地追踪和修复jsonp问题),那么你应该将forcast包装在你自己的诺言中。
.factory('WeatherService', function($q,$cordovaGeolocation) {
...
getForecast : function(api)
{
var deferred = $q.defer();
$.ajax({url : api, dataType : 'json', async : false,
success : function(res) {
defereed.resolve(res);
}
});
return defereed.promise;
}
您已经知道如何处理控制器代码中的承诺,因此我不会发布这些更改。