2017-09-18 8 views
0

こんにちは私は新しい角度にあり、約束を理解したいと思っていました。私は2つのhttp get(入れ子になった)別のものの中に1つ持っています。内部ループの値を使用して、以下のように外部get文のリンクを作成します。inner get文からout get文への値渡し

 $scope.loadtable = function (task){ 

     var bgUrl = "cloudantlink"; 

     $http.get(bgUrl) 
     .success(function (response) { 
      $scope.fileTableData =[]; 
      for(var i =0;i<response.rows.length;i++){ 

       var fileUrl = "cloudantURL"; 

       $http.get(fileUrl, {responseType:'arraybuffer'}) 
       .success(function (response) { 

        var file = new Blob([response], {type: 'application/pdf'}); 
        var fileURL = URL.createObjectURL(file); 

        $scope.content = $sce.trustAsResourceUrl(fileURL); 
        console.log("this is value of promise inside loop", $scope.content); 


       }).error(function(data){ 
       }); 


       console.log("this is value of promise outside loop",$scope.content); 

       var fileTableEntry = { 
         'download' : '<a href=\"'+$scope.content+'\">' + $scope.content+'</a>', 

        }; 
        $scope.TableData.push(TableEntry); 

      } 
      $scope.loadTable(); 

     }).error(function(data){ 

     }); 


    }; 

$ scope.contentの値は、常に2番目のループの外側では未定義またはnullです。誰かが最初のget文に値を渡す方法を提案することができますか?

答えて

0

$http.getのいずれかの非同期操作は、バックグラウンドで動作し、実際にこれを完了するまで待つことはありません。

終了後にコードを実行する場合は、Promise.thenメソッドを使用する必要があります。

この場合、これらの操作がすべて完了するのを待ってから、$scope.loadTableと関連するものを呼び出すことをお勧めします。

これを行うには、要求によって返された約束を保存し、$q.allで解決するのを待ちます。 $ qをコントローラの依存関係に追加することを忘れないでください。

var fileRequests = []; 
for(...) { 
    fileRequests.push($http.get(fileUrl) 
    .then(function success(response) { ... return fileUrl; })) 
} 

$q.all(fileRequests).then(function(fileUrls) { .. $scope.loadTable() }) 

また$scope.contentを毎回上書きされ、私はあなたが$scope.fileTableData[i]でURLを保存するためのものだと思います。

全コード:

 $scope.loadtable = function (task){ 
 

 
     var bgUrl = "cloudantlink"; 
 

 
     $http.get(bgUrl) 
 
     .success(function (response) { 
 
      var filePromises =[]; 
 
      for(var i =0;i<response.rows.length;i++){ 
 

 
       var fileUrl = "cloudantURL"; 
 

 
       // Saving the promises 
 
       filePromises[i] = $http.get(fileUrl, {responseType:'arraybuffer'}) 
 
       .then(function success(response) { 
 

 
        var file = new Blob([response], {type: 'application/pdf'}); 
 
        var fileURL = URL.createObjectURL(file); 
 

 
        // This will be the result when the promise is resolved 
 
        return $sce.trustAsResourceUrl(fileURL); 
 

 
       }, function error(data) { 
 
       }); 
 

 

 
      } 
 
      
 
      // Waiting for the promises 
 
      $q.all(filePromises).then(function(fileUrls) 
 
      { 
 
       // fileUrls contain the results returned by the success callback 
 
       $scope.TableData = fileUrls.map(function(url) { 
 
       return { 'download' : '<a href=\"'+url+'\">' + url+'</a>', }; 
 
       }) 
 
       $scope.loadTable(); 
 
      }) 
 
      
 

 
     }).error(function(data){ 
 

 
     });

+0

私はREPONSEタイプとして、内側のGETステートメントからBLOBのURLを作成するために使用される配列バッファであることを行うことができると思ういけません。私もq.allで試してみましたが、私にとってはうまくいきませんでした。値はループ内にありますが、タブ間を移動すると2回目にロードされます。初めて読み込まれることはありません。 – user6591323

+0

あなたのコードでは、ループ内の成功コールバックは、 '$ scope.TableData.push(TableEntry);と' $ scope.loadTable(); 'の両方の行の後に実行されます。これはレスポンスタイプと何をしているのかとは関係ありません。 $ q.allコールバックでfileTableEntry作成コードをsuccessコールバックに移動するか、それらのblob URLを配列に格納し、約束が解決された後にそれらを追加する必要があります。 – yscik

+0

$ scope.TableData.push(TableEntry);を移動できないという問題。 $ scope.loadTable(); 2番目のgetの内部は、最初のget文の応答からテーブルを作成する行を追加したいからです。また、コード部分についてもう少し詳しく説明できますか?私は約束を使用しましたが、あなたが示唆していることは異なるかもしれません。 – user6591323

関連する問題