将工厂服务数据获取到控制器以用于 promises

Getting factory service data to controller for use in view with promises

我正在尝试使用 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 来调用以使其在本地工作。

我知道我得到了成功的响应,因为如果我在 $.ajax 调用中 console.log(forecast) 我可以浏览天气数据。无论出于何种原因,我都无法将响应值保存到 ajax 调用的父范围中保存的 forecast var,然后将其 return 保存到控制器以在我的视图中使用$scope.forecast 变量。它总是 returning 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

好吧,如果您真的觉得有必要使用 ajax(可能更好地追踪和修复 jsonp 问题),那么您应该将预测包含在您自己的承诺中。

.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;
}

您已经知道如何在您的控制器代码中处理承诺,所以我不会 post 这些更改。