将工厂服务数据提供给控制器,以便在promises中使用

时间:2015-03-25 13:13:50

标签: javascript jquery ajax angularjs ionic

我正在尝试使用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

1 个答案:

答案 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;
}

您已经知道如何处理控制器代码中的承诺,因此我不会发布这些更改。