2016-03-31 3 views
-2

だから私はこれに似たオブジェクトの配列を持っている:非同期プログラミング - オブジェクトの配列をループし、APIからデータをフェッチして各オブジェクトにプロパティを変更する方法は?

[ { id: 123, info: 'text', number: 0 }, ... ]

私は、オブジェクトのIDを取り、それに関連した数を返すAPIを持っています。 JavaScriptを使用するフロントエンドアプリケーションでは、配列内の各オブジェクトを繰り返し処理し、そのNumberプロパティにこのAPIのデータを設定します。

私はAngularJSを使用していますが、これは私は、各オブジェクトに関連付けられた数フェッチ書いた関数である。

$scope.getNumber = function(id) { 
     $http.get('/api/getnumber/' + id) 
      .success(function(data) { 
       console.log(data.goings); 
       return data.number; 
      }); 
    } 

この機能が動作します。私の問題は、配列の各オブジェクトの数値プロパティを更新する方法がわかりません。私はそれをループしようとしましたが、.get()がデータを取得する前にループが実行されるので、これは機能しません。また、次のコードをhtmlで試してみました:

<div ng-repeat="obj in data"> 
     {{ getNumber(obj.id) || 0 }} 
</div> 

しかし、これは私のブラウザをクラッシュさせる無限ループを作成します。私はいくつかの検索を試みましたが、私は匹敵するケースを見つけるのが難しいです。どうすればこれを達成できますか?

+1

ゲッターは非同期にすることはできません。表示する値を設定するには、非同期コールバックが必要です。 – dandavis

+0

[非同期呼び出しからの応答を返すにはどうすればいいですか?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) –

+0

データを最初に戻す。次に、モデルのプロパティを設定します。 – ManoDestra

答えて

0

$http.get(..).success(..)は約束を返すため、このように使用することはできません。コントローラーをロードしてデータにアタッチすると、すべての数値がロードされることがありますか?

0

前述したように、success()関数は単に別の約束を返し、それ自体はあなたが望む値ではありません。成功関数のように値を返すのは、連鎖しているときにもう1つのに結果を渡す方法としてのみ役立ちます。

ユーザーがページと対話するように、これらの値が変更される可能性がある場合は、最良のオプションは常に表示され、$http約束によって更新されていることを(あなたの配列がng-repeat作品で繰り返し処理された)スコープ変数を持つことです。

ページが読み込まれるたびに1つしかないと予想される場合は、resolves(UIルーターを使用して解決する場合はlook here)を事前ロードすることができます。解決は、ページがロードされる前に約束をして、約束がすべて解決された後に実際のページのロードを開始することを可能にします。

必要な番号を一括して取得するコールがあるかもしれませんが、そうでない場合は、$q.all()を使用して個々のコールをグループ解決にすることができます。これにより、一連の約束を提供し、その結果の

もちろん、あらかじめロードしておき、ページの有効期間中に変更したい場合は、そうすることができます。