在angularjs工厂等待json响应

时间:2015-10-10 00:52:34

标签: json angularjs asynchronous

我越来越接近JSON响应了。在此示例中,事件变量在返回后填充,导致空白输出。我需要等待。我已经读过承诺是要走的路......但不确定它是如何工作的...在我的console.log中你可以看到数组但是Events.all();返回null。

    .factory('Events', function($http) {
         var events="";
          $http.get('http://appserver.falconinet.com/events.lasso').then(function(resp) {
            events = resp.data;
              console.log(events);
          }, function(err) {
            console.error('ERR', err);
            // err.status will contain the status code
          })
              return {
                all: function() {
                  return events;
                },
                get: function(eventId) {
                  for (var i = 0; i < events.length; i++) {
                    if (events[i].id === parseInt(eventId)) {
                      return events[i];
                    }
                  }
                  return null;
                }
              }

        })

这是我的控制器:

    // events

    .controller('EventsCtrl', function($scope, Events) {
        $scope.events = Events.all();
    })

    .controller('EventDetailCtrl', function($scope, $stateParams, Events) {
      $scope.event = Events.get($stateParams.eventId);
    })

2 个答案:

答案 0 :(得分:1)

以下将返回$http创建的承诺,并缓存所有事件的加载。

.factory('Events', function ($http, $q) {
   function loadEvents(id) {
       var promise = $http.get('http://appserver.falconinet.com/events.lasso', {cache: true});
       // return the promise 
       return promise.then(function (resp) {
           var events = resp.data;
           if (id) {
               // returns item or promise rejection
               return getEventById(id, events);
           } else {
               return events;
           }
       }).catch (function (err) {
           console.log('Events error ', err);
       });
   }

   // helper function , returns event or  promise rejection
   function getEventById(id, events) {
       for (var i = 0; i < events.length; i++) {
           if (events[i].id === parseInt(eventId)) {
               return events[i];
           }
       }
       return $q.reject('None found');
   }

   return {
       all: function () {
           return loadEvents();
       },
       get: function (eventId) {
          return loadEvents(eventId);
       }
   }

});

然后在控制器中,您需要在promise then回调

中恢复数据
.controller('EventsCtrl', function($scope, Events) {
     Events.all().then(function(events){
         $scope.events = events;
     });
})

.controller('EventDetailCtrl', function($scope, $stateParams, Events) {

     Events.get($stateParams.eventId).then(function(event){
         $scope.event = event;
     });
})

答案 1 :(得分:-1)

正如您所提到的,将实际流程包装在新承诺中是可行的方法。为了做到这一点,这家工厂的使用需要一些调整。 Lemme尝试从您的脚本中编写示例,但我不保证在第一次尝试时使用它:)

.factory('Events', function($http, $q) {
  return {
    all: function() {
      var myPromise = $q.defer();

      $http.get('http://appserver.falconinet.com/events.lasso')
      .then(function(resp) {
        myPromise.resolve(resp.data);
      }, function(err) {
        myPromise.reject(err);
      });

      return myPromise.promise;
    },
    get: function(eventId) {
      var myPromise = $q.defer();

      $http.get('http://appserver.falconinet.com/events.lasso')
      .then(function(resp) {
        var events = resp.data;
        for (var i = 0; i < events.length; i++) {
          if (events[i].id === parseInt(eventId)) {
            myPromise.resolve(events[i]);
          }
        }
      }, function(err) {
        myPromise.reject(err);
      });

      return myPromise.promise;
    }
  }
});

除了所有内容之外,这可以在您放置时得到改善,但在知道如何处理承诺之后我发现这非常简单。

使用它们就像这样:

// Get all
Events.all().then(function(events){
  $scope.events = events;
});

// Get one
Events.get(eventId).then(function(event){
  $scope.events = event;
});