web-dev-qa-db-ja.com

AngularJSサービスからデータを読み込む

ビューに入力されたサービスからデータを取得する際に問題が発生しました。そのように定義されたサービスがあります

app.factory('nukeService', function($rootScope, $http) {
    var nukeService = {};

    nukeService.nuke = {};

    //Gets the list of nuclear weapons
    nukeService.getNukes = function() {
        $http.get('nukes/nukes.json')
            .success(function(data) {
                nukeService.nukes = data;
            });

        return nukeService.nukes;
    };

    return nukeService;
});

そして私のコントローラー

function NavigationCtrl($scope, $http, nukeService){



    /*$http.get('nukes/nukes.json').success(function(data) {
        $scope.nukes = data;
    });*/

    $scope.nukes = nukeService.getNukes();

}

コントローラから$ http.getを使用すると、データは正常に入力されますが、サービスからデータを呼び出そうとしても、何も得られません。クエリが非同期であることを理解していますが、データが返された後の$ scope変数の設定方法を理解するのに苦労しています。 $ rootscopeを使用してイベントをブロードキャストし、コントローラーでリッスンすることはできますが、これはこれを実現する正しい方法のようには思えません。これを正しい方法で行う方法についてのアドバイスをいただければ幸いです。

14
jamesamuir

これで問題は解決すると思います

app.factory('nukeService', function($rootScope, $http) {
    var nukeService = {};

    nukeService.data = {};

    //Gets the list of nuclear weapons
    nukeService.getNukes = function() {
        $http.get('nukes/nukes.json')
            .success(function(data) {
                nukeService.data.nukes = data;
            });

        return nukeService.data;
    };

    return nukeService;
});

function NavigationCtrl($scope, $http, nukeService){

    $scope.data = nukeService.getNukes();

    //then refer to nukes list as `data.nukes`

}

これはオブジェクト参照の問題です。

nukeService.getNukes()を呼び出すと、オブジェクトaへの参照が取得され、変数$scope.nukesはそのメモリ位置を参照します。

リモートサーバー呼び出しの後、nukeService.nukes = data;を設定すると、オブジェクトaは変更されません。代わりに、nukeService.nukesがオブジェクトaの参照からオブジェクトbに変更されます。しかし、$scope.nukesはこの再割り当てを認識しておらず、オブジェクトaを指しています。

この場合の私の解決策は、オブジェクトaにプロパティdataを渡して、参照をaに変更するのではなく、データプロパティのみを変更することです。

27
Arun P Johny

これは次のようになります。 NickWiggillのコメントで述べたように、promiseを返さない場合、undefinedはnukeService.dataに割り当てられます。

app.factory('nukeService', function($rootScope, $http) {
    var nukeService = {};
    //Gets the list of nuclear weapons
    nukeService.getNukes = function() {
       return $http.get('nukes/nukes.json');
    };

    return nukeService;
});


  function NavigationCtrl($scope, $http, nukeService){
     nukeService.getNukes().then(function(response){

        $scope.data = response.data;
    });

   }
9
Ganesh

私がやっていることは、サービスから直接データを公開し、このデータを初期化するメソッドを持っているということです。これの何が問題になっていますか?

サービス:

app.factory('nukeService', function($scope, $http) {
    var data = {};
    data.nukes = [];

    //Gets the list of nuclear weapons
    var getNukes = function() {
        $http.get('nukes/nukes.json').success(function(data) {
                data.nukes = data;
        });
    };

    // Fill the list with actual nukes, async why not.
    getNukes();

    return {
        data : data
        // expose more functions or data if you want
    };
});

コントローラ:

function NavigationCtrl($scope, nukeService){
     $scope.data = nukeService.data;
     //then refer to nukes list as `$scope.data.nukes`
}
3