2013-10-08 12 views
11

私はAngularJSの約束のコンセプトを頭で囲むことができません。あなたが見ることができるようにAngularJS:非同期呼び出しを待っています

var packingProvider = angular.module('packingProvider',[]); 

packingProvider.provider('packingProvider',function(){ 
    return{ 
     $get: function($http){ 
      return{ 
       getPackings: function(){ 
        $http.post('../sys/core/fetchPacking.php').then(function(promise){ 
         var packings = promise.data; 
         return packings; 
        }); 
       } 
      } 
     } 
    } 
}); 

が、これは私が私のメインのアプリケーションでデータを受信することを使用している場合は、今すぐオブジェクト

を返します方法getPackings()を、提供:

私はプロバイダを持っていますプロセスをリファクタリングすることなく、私はこれを行うだろうか

var packings = packingProvider.getPackings(); 

console.log(packings); // undefined 

:、呼び出しは、私は、データのために「待つ」しなければならない問題が生じ、非同期になります私のメインコントローラに?

+2

どのように 'getPackings''も返す'について「約束」? – Kita

答えて

7

あなたのthenメソッド内の戻り値は、それがそうだと思われるときに戻っていません。後で戻ってきます。

var packings = packingProvider.getPackings();の文では、$httpから返される約束が非同期であるため、戻り値は未定義です。つまり、$http.postへの呼び出しが発生すると、を完了せず、関数が戻ります。何も返さないJS関数では未定義に戻ります。 postコールは後で完了し、return packings;を実行し、どこにも返されません。

getPackingsメソッドはおそらく$http.postから約束を返すべきです。こうすることで、このメソッドを使用したいコードであれば、約束に直接thenを呼び出して、必要な方法で値を設定できます。コントローラーでは、その約束を直接$scopeに割り当て、それをあなたの視点で使用することができます。具体的な機能を説明した素晴らしい投稿があります:http://markdalgleish.com/2013/06/using-promises-in-angularjs-views/

ちなみに、あなたは長年にわたるサービス宣言があるようです。このようなものに短縮しない理由は何ですか?

私はAngularJSには比較的新しいですが、私はそのタイプの入力で何の利得も見ません。 (=

+0

ありがとう今までのところ私は、より高い構成可能性のために、単純なサービスを介してプロバイダを選択することは常に良い考えであると考えていたでしょう。デフォルトごとにプロバイダーを選択するときに不利な点はありますか? – user2422960

+1

多くの場合、必要のないコードがたくさんあります。実際、どのような構成可能性が必要かによって異なります。値を設定していますか?なぜあなたのサービスに 'value'や' constant'を注入しないのですか?ライブラリーで使用するサービスを作成していた場合は、 'provider'呼び出しを使用してライブラリのコンシューマーがあなたが注入しているこれらの魔法の値を知る必要がないように見えますが、そうでなければまっすぐな'サービス 'もっとシンプルに。 –

7

はメインアイデア

packingProvider.getPackings().then(function(packings){ 
    console.log(packings); 
}); 
その後

var packingProvider = angular.module('packingProvider',[]); 

packingProvider.provider('packingProvider',function(){ 
    return{ 
     $get: function($http){ 
      return{ 
       getPackings: function(){ 
        return $http.post('../sys/core/fetchPacking.php').then(function(response){ 
         return response.data; // packings 
        }); 
       } 
      } 
     } 
    } 
}); 

を試してみてください:あなたはgetPackings関数から約束のオブジェクトを返す必要があります。同期を呼び出すことができるかどうかは不明ですが、そうすることはほとんど間違いありません。

$scope.packings = packingProvider.getPackings(); 
を:あなたはあなたのコントローラ上の「パッキン」モデルオブジェクトを作成し、2方向性結合のために使用したい場合は、データが伝わってくるよう。また、あなたが安全に角度が、すぐに解決される約束のオブジェクトを割り当てることができます上記のコードの行がもはや結合二方向性を生じないように、1.2.0-rc.3約束のアンラップのよう

UPDATEは、(https://github.com/angular/angular.js/blob/master/CHANGELOG.md#120-rc3-ferocious-twitch-2013-10-14)廃止されました。

+1

別の重要な点を忘れてしまった:あなたが好きなだけ "チェーン"することができます: "then"から返された値は結果として "then"に引き渡されます –

+0

ありがとう、本当に助けてくれました –

1

jQueryでDeferreds/Promisesを使用する方法を示すリソースがたくさんあります。この障害を乗り越えるのに役立つものを探してみてください。アフリカ、AngularJSの約束はjQueryの約束と同じです。

jQueryの約束は、このようなものに使用されます。

var getPackings = function() { return $.get('../sys/core/fetchPacking.php'); }; 
var packings; 
$.when(getPackings()).then(function(data){ packings = data; console.log(packings) }); 

そのjQueryのAjaxの呼び出しは、このようななどの.done、.success、などの機能を持っていても心に留めておいてくださいと...それは、ジェネリックのDeferredを置き換えます。 when()。then()関数。

上記のjQueryメソッドでは、データを設定して.then()関数で出力する必要があることがわかります。非同期処理が他の場所で行われることは保証できないためです。 .then()関数の中で、あなたの処理を継続どんな機能だから、理想的に、あなたはそうのように呼び出します。

$.when(myAsyncFunc()).then(myAppCanContinue(dataReturnedByAsyncFunc)); 

角度が同じロジックに従うとしています。上記を理解すれば、これをAngularでどのように達成するのかを理解することがより簡単になります。また、簡単な例与え、この記事をチェックアウト:動作するようにあなたのコードを取得するためにhttp://markdalgleish.com/2013/06/using-promises-in-angularjs-views/

を、あなたはこのような何かをする必要があります。

packingProvider.provider('packingProvider',function(){ 
    return{ 
     $get: function($http){ 
      return{ 
       getPackings: function(){ 
        return $http.post('../sys/core/fetchPacking.php'); 
       } 
      } 
     } 
    } 
}); 
var packings = packingProvider.getPackings(); 

packings.then(function(data) { console.log(data)}); 
関連する問題