Angularjs 如何在angular factory中存储http服务中的数据

Angularjs 如何在angular factory中存储http服务中的数据,angularjs,Angularjs,我希望使用服务全局存储/api/login.json中的值,但我认为我有一些计时问题。控制器中的console.log语句告诉我scope.login对象未定义 我错过了什么 谢谢 工厂服务: myApp.factory('LoginFactory', ['$http', function($http){ this.data; $http.get('/api/login.json').success(function(data) { this.data = da

我希望使用服务全局存储/api/login.json中的值,但我认为我有一些计时问题。控制器中的console.log语句告诉我scope.login对象未定义

我错过了什么

谢谢

工厂服务:

myApp.factory('LoginFactory', ['$http', function($http){

    this.data;
    $http.get('/api/login.json').success(function(data) {
        this.data = data;
    });

    return {
        getData : function(){
        return this.data;
    }
  }
}]);
控制器:

myApp.controller('AccountsCtrl', ['$scope', 'Accounts', 'LoginFactory', function($scope, Accounts, LoginFactory){
  $scope.login = LoginFactory.getData();
  console.log('$scope.login: %o', $scope.login);    
  $scope.accounts = Accounts.index();

}]);

在此上下文中,您可能应该避免使用
this
关键字。最好只声明一个新变量

myApp.factory('LoginFactory', ['$http', function ($http) {
    var data;
    $http.get('/api/login.json').success(function (d) {
        data = d;
    });
    return {
        getData: function () {
            return data;
        }
    };
}]);
尽管如此,您仍然会遇到种族问题,因此我也建议您使用承诺链接

myApp.factory('LoginFactory', ['$http', function ($http) {
    var promise = $http.get('/api/login.json');
    return {
        getData: function (callback) {
            promise.success(callback);
        }
    };
}]);
甚至是有条件的

myApp.factory('LoginFactory', ['$http', function ($http) {
    var data;
    return {
        getData: function (callback) {
            if(data) {
                callback(data);
            } else {
                $http.get('/api/login.json').success(function(d) {
                    callback(data = d);
                });
            }
        }
    };
}]);
但最后两种方法需要您重写控制器

myApp.controller('AccountsCtrl', ['$scope', 'Accounts', 'LoginFactory', function($scope, Accounts, LoginFactory){
  LoginFactory.getData(function(data) {
      $scope.login = data;
      console.log('$scope.login: %o', $scope.login);    
      $scope.accounts = Accounts.index(); //this might have to go here idk
  });
}]);

您对
this
关键字有问题,而且您没有正确处理http.get中的承诺

我会这样写:

myApp.factory('LoginFactory', ['$http', function($http){

    return {
        getData : function(){
        return $http.get('/api/login.json');
    }
  }
}]);


myApp.controller('AccountsCtrl', ['$scope', 'Accounts', 'LoginFactory', function($scope, Accounts, LoginFactory){
  $scope.login = LoginFactory.getData().success(function(data){
     console.log(data);
     console.log('$scope.login: %o', $scope.login); 
  });

}]);

扩展@LoganMurphy答案。使用promise并仍然添加回调是完全不可取的。编写服务的更好方法可能是

myApp.factory('LoginFactory', ['$http', function ($http, $q) {
    var data;
    return {
        getData: function () {
            if(data) {
                return $q.when(data);
            } else {
                return $http.get('/api/login.json').then(function(response){
                    data = response;
                    return data;
                });
            }
        }
    };
}]);

问题是这个关键字的上下文在get内部和get外部是不同的…为什么不只是var数据变量我尝试了var数据变量(var data={};),但它并没有任何影响,除了现在,我只是得到了一个空对象。当然,这并没有变为变量那么简单。你必须在其他地方删除this关键字,并更改success函数的局部变量的名称。是的,我认为这是隐含的:)谢谢,我刚刚在第二个代码块中尝试了你的建议,效果很好。我只需要更新控制器中的调用:LoginFactory.getData(函数(结果){$scope.login=result;});如果您能在控制器中添加更改,我将接受并更新您的答案。谢谢我认为OP希望缓存ajax get请求的结果……不幸的是,您的解决方案没有做到这一点