2015-10-10 64 views
2

我在尋求JSON響應方面越來越近了。在這個例子中,事件變量在返回後填充,導致空白輸出。我需要它等待。我已經讀過,承諾是要走的路......但不知道如何工作...在我的console.log中,你可以看到數組,但Events.all();返回null。在angularjs工廠等待json響應

.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); 
    }) 
+0

做您的端點數據有返回單個事件的能力,當發送ID控制器?或者你是將所有文件存儲在一個文件中? – charlietfl

+0

它只是來自服務器的一個響應。我可以讓服務器做任何我想做的事情,但是如果我硬編碼事件變量,這會起作用,但是由於http.get是異步的,它會在後臺觸發並且在Events.all被調用之前沒有完成。這是一種可移動的離子應用。 –

回答

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

}); 

然後在您需要resove在承諾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; 
    }); 
}) 
+0

這適用於/ events選項卡。棒極了!但是,單擊選項卡上,我得到一個錯誤: '類型錯誤:無法讀取屬性「然後」 undefined'也是我得到:'的ReferenceError:EVENTID不defined' –

+0

哎呀我'GET'冷落'return' ...現在修復瞭如果未定義'eventId'需要查看路由配置的 – charlietfl

+0

。應確保它存在於控制器中,首先將 – charlietfl

-1

正如你提到的,包裹你的實際過程中一個新的承諾是要走的路。爲了這樣做,這個工廠的使用需要一些調整。讓我再嘗試從您的腳本編寫的樣本,但我不能保證得到它的工作在第一次嘗試:)

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