6

プロジェクトをピックアップして、サービスからコントローラーにデータを返そうとしています。私はこれで約12時間過ごし、さまざまな方法を試しました。それらはすべて、通常、この同じ種類の「欠落データ」をもたらします。

私はもう試した

  • $http の代わりに $resource を使用する
  • $http.getpromise を使用せずにコントローラ内に権利を配置する
  • 返品のない実際のサービス(工場ではなく)としてのサービス
  • さまざまな形式でデータを返すさまざまな方法でファクトリを構築する
  • setTimeout と $apply の使用

私が今持っているものは、手に入れることができるほどシンプルだと感じています。私が読んだものはすべて、これが機能するはずだと言っています

angularjs-load-data-from-service

angular-controller-cant-get-data-from-service

angularjs-promises-not-firing-when-returned-from-a-service

angularjs-promise-not-resolving-適切に

angularjs-約束

これらのリンクは今日のものです。

過去に $scopes が複数のコントローラーが使用されているときにデータを取得しないのを見たので、$scope の問題があるのではないかと考えましたが、サイトはindex.html<body ng-app="myApp" ng-controller="BodyCtrl">でコントローラーをセットアップとして宣言するだけです。メインのapp.jsは、(私が信じている ui-router からの) 状態を次のように使用します...

.state('app.view', {
    url: '/view',
    templateUrl: 'views/view.tpl.html',
    controller: 'MyCtrl'
   })

コントローラーを別のページにアタッチします。また、サイトにはサービスからデータを取得する他のコントローラーがいくつかありますが、最初にテンプレートとして調べましたが、データとリターンは私が取得しようとしているものよりもはるかに複雑です. 要するに、コントローラーはサービスから提供されたデータにアクセスしています。それらはすべて $resource を使用しています。これが、私がこの問題を開始した方法です。$http は機能するはずなので、これを使い続けています。「より高いレベル」に移る前に、これを機能させたいと思っています。また、エンドポイントから GET するだけでよいので、$resource はやり過ぎだと感じました。

サービス

.factory('MyService', ['$http', '$q', '$rootScope', function ($http, $q, $rootScope) {
    var defer = $q.defer();
    var factory = {};
    factory.all = function () {
        $http({method: 'GET', url: 'http://URLtoJSONEndpoint'}).
            success(function (data, status, headers, config) {
                console.log('data success', data);
                defer.resolve(data);
            }).
            error(function (data, status, headers, config) {
                console.log('data error');
                defer.reject(data);
            });

        return defer.promise;
    };
    return factory;
}]);

コントローラ

.controller('MyCtrl', ['$scope', '$state', '$stateParams', '$rootScope', 'MyService', '$q', function ($scope, $state, $stateParams, $rootScope, MyService, $q) { 
...
...
$scope.data = null;
$scope.object = MyService;
$scope.promise = MyService.all();

MyService.all().then(function (data) {
    $scope.data = data;
    console.log("data in promise", $scope.data);
})
console.log("data", $scope.data);
console.log("object", $scope.object);
console.log("promise", $scope.promise);

$http({method: 'GET', url: 'http://URL'}).
        success(function (data, status, headers, config) {
            $scope.data = data;
            console.log('data success in ctrl', data);
        }).
        error(function (data, status, headers, config) {
            console.log('data error');
        });

    console.log("data after ctrl", $scope.data);


    angular.forEach($scope.data, function (item) {
        // stuff that I need $scope.data for
    }

コンソールログ

これは私のコンソール ログです。実際のデータではなく、多くの情報を取得できます。これが私が必要とするものです。私は頭がおかしくなり、.then(function (data) {必要なコントローラー内のすべての関数をキャプチャするように拡張しました$scope.data。それは列車事故でした。

***data null***
object Object {all: function}
promise Object {then: function, catch: function, finally: function}
***data success after ctrl null***
data success in ctrl Array[143]
data success Array[143]
data in promise Array[143]
data success Array[143]

私が知る限り、これはうまくいくはずですが、他にどこに問題があるのか​​ わかりません! たぶん、約束がどのように機能するか、または解決するかを理解していません。以前に別のプロジェクトでAngularを使用したことがありますが、最初にそこにいて、それがどのようにまとめられているかを理解していました. このプロジェクトは別の方法で構成されており、よりカオスに感じられます。単純化したいのですが、単純なデータを返すことさえできないようです!

これが機能しない理由を特定するために提供できるヘルプ/フィードバックに感謝します。ありがとうございます!

編集: では、問題は、なぜconsole.log("data", $scope.data)約束の前にnullに戻ってくるのですか?

コントローラーのもう少し下に私はこれを持っています

angular.forEach($scope.data, function (item) {
// stuff
}

データにアクセスできないようです。

EDIT2:コントローラー内で使用していたものを、コントローラーのコンソールログと実際に必要な forEach とともに追加しまし$http.get$scope.data

EDIT3:

更新されたサービス

.service('MyService', ['$http', function ($http) {
    function all() {
        return $http({
            url: 'http://URL',
            method: 'GET'
        });
    }

    return {
        all: all
    }
}]);

更新されたコントローラー

MyService.all().success(function (data) {
        $scope.data = data;

        angular.forEach($scope.data, function (item) {

            // Turn date value into timestamp, which is needed by NVD3 for mapping dates
            var visitDate = new Date(item.testDate).getTime();

            switch (item.Class) {
                case "TEST":
                    testData.push(
                        [
                            visitDate,
                            item.Total
                        ]
                    );

            }

        });

        console.log("test Data in success", testData);
    });


$scope.testData = [
        {
            "key": "Test",
            "values": testData
        }
    ];

そのため、ビュー ( nvd3$scope.testDataチャート) で使用する必要があり、データを取得していません。

解決

MyService.all().success(function (data) {
        $scope.data = data;

        angular.forEach($scope.data, function (item) {

            // Turn date value into timestamp, which is needed by NVD3 for mapping dates
            var visitDate = new Date(item.testDate).getTime();

            switch (item.Class) {
                case "TEST":
                    testData.push(
                        [
                            visitDate,
                            item.Total
                        ]
                    );
            }

        });

        console.log("test Data in success", testData);

        $scope.testData = [
        {
            "key": "Test",
            "values": testData
        }
    ];
    });
4

2 に答える 2

5

これは、サービスがどのように見えるかを示す非常に単純な例です。

app.service('MyService', ['$http', function ($http) {
  function all() {
    return $http({
      url: 'data.json',
      method: 'GET'
    });
  }

  return {
    all: all
  }
}]);

コントローラーでは、次のように使用します。

app.controller('AppCtrl', ['$scope', 'MyService', function ($scope, MyService) {
  $scope.data = null;

  MyService.all().success(function (data) {
    $scope.data = data;

    // init further handling of `.data` here.
  });
}]);

デモ: http://plnkr.co/edit/l8pF8Uaa312A8kPtaCNM?p=preview


コンソールがログを記録する理由の質問に答えるにはdata null: これは、非同期呼び出しが完了する前にログが発生するためです。

于 2014-05-07T14:58:36.370 に答える
0

私は同じ問題に直面しています。will be avaiable$rootScopeではなく promise 内で使用することで、その問題を解決します。$scope.So $rootScope.dataconsole.log

于 2015-12-03T09:38:36.253 に答える