2016-03-25 10 views
0

Iは、次のコントローラを持っている:は条件付きコントローラで同期または非同期オブジェクトを受信する(角度、イオン)

.controller('SponsorsCtrl', function ($scope, Sponsors, $http) { 
    $scope.$on('$ionicView.enter', function() { 
     Sponsors.all($http).then(function (data) { 
       $scope.sponsors = data; 
       var check = "check"; 
       })  
    }); 
}) 

I非同期オブジェクトを受信したため、「その後」で使用するための理由。今、私は、また、次のサービスを介して同期オブジェクトを受け取ることができる: (関数(){ 角度.module( 'sponsors.services'、[]) .factory( 'スポンサー'、スポンサー);

Sponsors.$inject = []; 

function Sponsors() { 

    var service = { 
     all: all, 
     allServer: allServer, 
     allLocal: allLocal, 
     get: get, 
     getTimeStamp: getTimeStamp 
    }; 
    return service; 

    function all($http) { 
     var timeDifference = (Date.now() - this.getTimeStamp()); 

     if (timeDifference < 600000) { 
      return this.allLocal(); 
     } 
     else {     
      return this.allServer($http);  
     } 
    } 

    function allServer($http) { 
     return $http.get("http://dream16backend.azurewebsites.net/api/dream16/sponsors") 
        .then(function (resp) { 
         //Set localstorage, create timestamp and return the data 
         window.localStorage.setItem('sponsors', resp.data); 
         window.localStorage.setItem('sponsorsTimeStamp', Date.now()); 
         var bla = JSON.parse(window.localStorage.getItem('sponsors')); 
         return bla; 
        }, function(err) { 
         console.log('ERR', err); 
        });    
    } 

    function allLocal() { 
     return JSON.parse(window.localStorage.getItem('sponsors')); 
    } 

    function get(adressId) { 
     for (var i = 0; i < sponsors.length; i++) { 
      if (sponsors[i].id === parseInt(sponsorId)) { 
       return sponsors[i]; 
      } 
     } 
     return null; 
    } 

    function getTimeStamp() {   
     return window.localStorage.getItem('sponsorsTimeStamp'); 
    } 
} 

})(); この方法では、非同期呼び出し(function allServer)のみが機能しますが、同期は失敗します。サービスのすべての機能に「then」機能を移すことが修正されたと思います。これにより、同期呼び出し(function allLocal)は動作しますが、非同期呼び出しは失敗します。それ以外の条件は次のようになります。

else { 
       this.allServer($http).then(function (data) { 
        return data; 
       }) 
      } 

そして、コントローラは次のようになります。

.controller('SponsorsCtrl', function ($scope, Sponsors, $http) { 
    $scope.$on('$ionicView.enter', function() { 
     $scope.sponsors = Sponsors.all($http); 
     var check = "check"; 
    }); 
}) 

私は、コール自体が(テスト変数を経由して「BLA」)が動作していることを確認しました。私はまた、コントローラーがコントローラを実行することを確認var check = "check";非同期コードを実行する前に私はここで間違って何をしていますか?

+0

すべてのメソッドの引数として渡す代わりに '$ http'をサービスに注入する方がずっと簡単で、コントローラに注入する必要はありません。 '$ http'の最初の' then'は、実際のサーバレスポンスのためにアクセスする必要がある 'data'プロパティを持つレスポンスオブジェクトを返します。 – charlietfl

+0

@charlietfl $ httpのヒントをありがとう、しかし私は実際にallServer関数を介して応答からデータを取り出します。 'this.allServer($ http);によって返されたオブジェクトが実際に正しいデータであることを確認しました。問題は、私のコントローラが非同期サービスの結果を受け取る前に実行していることです。 – Kai

答えて

1

OK ... Sponsors.all()の両方のインスタンスについて約束を返す必要があります.1インスタンスはすでに$http約束を返すためです。

$qのサービスでは、allLocal()も約束を返します。

function allLocal() { 
    return $q.resolve(JSON.parse(window.localStorage.getItem('sponsors'))); 
} 

とコントローラに、あなたは、コントローラで$httpを注入し、それだけで$httpを注入する方が簡単だろうと、サービスに渡しする必要はありません上記のコメントで述べたようにthen()

$scope.$on('$ionicView.enter', function() { 
    Sponsors.all($http).then(function(data){ 
     $scope.sponsors = data; 
    }); 
    var check = "check"; 
}); 

を使用する必要があります実際に必要とされている場所でサービスを提供しています

1

私はあなたに次の解決策を提案します。どちらの場合も "Promise"オブジェクトを返します。 allLocal機能のためには、次のようになります。

function allLocal() { 
    var deferred = $q.defer(); 
    deferred.resolve(JSON.parse(window.localStorage.getItem('sponsors'))); 
    return deferred.promise; 
} 

だから今、あなたはどちらの場合も.then使用することができます - 同期および非同期

1

私はあなたのサービスに$ HTTPサービスを注入するお勧めを...すなわち、

.factory('MyService', function ($http, $timeout,$q) { 
    var service = { 
      all: all, 
      allServer: allServer, 
      allLocal: allLocal, 
      get: get, 
      getTimeStamp: getTimeStamp 
     }; 
     return service; 

     function all() { 
      var timeDifference = (Date.now() - this.getTimeStamp()); 

      if (timeDifference < 600000) { 
       return this.allLocal(); 
      } 
      else {     
       return this.allServer($http);  
      } 
     } 

     function allServer() { 
      return $http.get("http://dream16backend.azurewebsites.net/api/dream16/sponsors") 
         .then(function (resp) { 
          //Set localstorage, create timestamp and return the data 
          window.localStorage.setItem('sponsors', resp.data); 
          window.localStorage.setItem('sponsorsTimeStamp', Date.now()); 
          var bla = JSON.parse(window.localStorage.getItem('sponsors')); 
          return bla; 
         }, function(err) { 
          console.log('ERR', err); 
         });    
     } 

     function allLocal() { 
      var dfd = $q.defer(); //create a deferred object 
      $timeout(function(){ 
       var localResponse = JSON.parse(window.localStorage.getItem('sponsors'));; 
       dfd.resolve(localResponse); //resolve the localObject 
      }); 
      return dfd.promise; //return the promise object so controller gets the .then function 
     } 

     function get(adressId) { 
      for (var i = 0; i < sponsors.length; i++) { 
       if (sponsors[i].id === parseInt(sponsorId)) { 
        return sponsors[i]; 
       } 
      } 
      return null; 
     } 

     function getTimeStamp() {   
      return window.localStorage.getItem('sponsorsTimeStamp'); 
     } 
}) 
+0

これは間違いなく道のりです。 –

0

あなたがまたは約束を返さない場合がありサービスを扱っている場合は、そのAPI呼び出しをラップする$q.when(...)を使用して$qが残りを処理させることができます。

あなたの場合には、のようにサービスapiをラップして定期的な約束として使用するだけです。

チェックアウトhttps://github.com/kriskowal/q/wiki/API-Reference#promise-methods

関連する問題