16

編集

最初の答えは洗練されたものですが、この質問とstackoverflowに関する別の質問で何度か述べたように、問題は、データが実際に到着する前にサービスとコントローラーが実行することです。

(最初の回答に対する最後のコメント:)

はい、問題は、サービスが実行されてすべてがコントローラーに返された後に API 呼び出しが終了することです。到着?

繰り返し言っているように、データの取得が成功した後に配列にデータを入力するサービスを作成する方法と、これがすべて発生した後にデータを取得するコントローラーを作成するにはどうすればよいですか。注文。


私はこのコードを持っています:

 var deferred = $q.defer();
            $http.get('../wordpress/api/core/get_category_posts/?category_id=14 ').success(function(data) {
                //we're emptying the array on every call
                theData = [];
                catName = data.category.slug;
                theData = data;
                theData.name = catName;
                aggregatedData.push(theData);
            });
            $http.get('../wordpress/api/core/get_category_posts/?category_id=15 ').success(function(data) {
                theData = [];
                catName = data.category.slug;
                theData = data;
                theData.name = catName;
                aggregatedData.push(theData);
            });
            $http.get('../wordpress/api/core/get_category_posts/?category_id=16 ').success(function(data) {
                theData = [];
                catName = data.category.slug;
                theData = data;
                theData.name = catName;
                aggregatedData.push(theData);
            });
            $http.get('../wordpress/api/core/get_category_posts/?category_id=17 ').success(function(data) {
                theData = [];
                catName = data.category.slug;
                theData = data;
                theData.name = catName;
                aggregatedData.push(theData);
            });
            //deferred.resolve(aggregatedData);
            $timeout(function() {
                deferred.resolve(aggregatedData);
            }, 1000);
            /*//deferred.reject('There is a connection problem.');
            if (myservice._initialized) {
                $rootScope.$broadcast('postsList', deferred.promise);
            }*/
            //myservice._initialized = true;
            myservice = deferred.promise;
            return deferred.promise;

私の人生では、結果の配列を defer に渡すときになぜタイムアウトを設定する必要があるのか​​ 理解できませんか?

情報が来るのを待ってから約束を返すという原則はありませんか?その1秒のポイントは何ですか?私が理解していることから、延期は、APIが結果を返し、約束されたデータを返すのに必要な限り待つことができるはずです。

私は本当に混乱しています.タイムアウトを設定したときだけ、コントローラーでデータを受信して​​いなかったため、過去2時間壁に頭をぶつけました.

4

2 に答える 2

60

IMHO でこれを行うには、はるかに賢い (そしてエレガントな) 方法があると思います$q.all

以下のコードを見てください。

すべての結果を大きな配列に集約して一度にデータを返すことを想定しています。

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

myApp.factory('myService', function ($http, $q) {
    return {
        getAllData: function () {
            return $q.all([
                $http.get('../wordpress/api/core/get_category_posts/?category_id=14'),
                $http.get('../wordpress/api/core/get_category_posts/?category_id=15'),
                $http.get('../wordpress/api/core/get_category_posts/?category_id=16'),
                $http.get('../wordpress/api/core/get_category_posts/?category_id=17')
            ]).then(function (results) {
                var aggregatedData = [];
                angular.forEach(results, function (result) {
                    aggregatedData = aggregatedData.concat(result.data);
                });
                return aggregatedData;
            });
        }
    };
});

aggregatedDataを介してすべての非同期呼び出しが完了すると、 のみ生成されることが上記でわかります$q.all

たとえば、サービスを依存関係としてコントローラーの1つに含め、次のようにサービスを呼び出すだけですmyService.getAllData()

それが役立つことを願っています。または、完全に機能する例が必要な場合はお知らせください。提供できます。:)

于 2013-09-07T15:32:36.340 に答える
11

呼び出しは非同期ですが、$http.get遅延を解決する前にすべてが完了するまで待機していません。ここでは、呼び出しが 1 秒以内に完了する時間があることが幸運であるため、タイムアウトで機能しますが、これはまったく信頼できません。

ここで完全な解決策を繰り返すことはしませんが、別の同様の問題に対する私の回答を見てください。

于 2013-09-07T15:28:52.310 に答える