(Angularjs)如何$ http.get数据并将其存储在服务中

时间:2014-01-29 22:31:50

标签: javascript json angularjs

正如你将看到我在AngularJS,JS和网络开发中的新手=)真的很抱歉,但我试着。

我尝试用AngularJS控制器构建一个庞大的webform(大约200个不同的字段)。我需要从控制器访问根数据源。 AngularJS团队要求不要仅仅为了存储数据而提供服务,但我想为加载和保存数据提供服务(在服务器上启动.json文件)。

服务:

AppName.factory('MasterData', ['$rootScope', '$http', '$q', '$log', 
    function($rootScope, $http, $q, $log) {

    var responseData;
    $http.get('/getdata.php').then(function (response) {
        responseData = response.data;
        console.log(response.data);
    });

    return responseData;

}]);

控制器:

AppName.controller('justController', ['$scope', 'MasterData', '$log',
    function ($scope, MasterData, $log) {
        $scope.data = MasterData.justControllerSectionData;
        console.log(MasterData);
    }
]);

控制器返回undefined。但是来自服务的console.log返回对象。 我觉得问题太容易了,但我找不到如何解决它:( 此外,我不能使用像.getData()这样的函数从控制器到服务,因为每次任何控制器加载时它都会从服务器询问数据。我在AngularJS应用程序中有12-14个控制器的路由(完整的webform除以部分),我认为从后端获取数据一次很好。

P.S。我认为承诺存在问题,但是当我尝试使用这样的代码时:

var defer = $q.defer();
$http.get('/getdata.php').success(function(data){
    defer.resolve(data);
});
return defer;

我有决心,拒绝的对象等等。真的无法理解我能用它做什么:(

帮我获取控制器中的数据:)

2 个答案:

答案 0 :(得分:18)

您的代码不起作用,因为您在服务中提供给success()的回调是异步调用的;服务返回后,即:

序列是这样的:

  1. 运行MasterData中的function$http.get请求已启动并附加了promise回调。此回调中引用了responseData(又称“已关闭”)。
  2. 该函数从服务返回到您的控制器。尚未设置responseData,这不会阻止父作用域函数返回。
  3. $http.get成功,并在服务中设置responseData,但控制器无法访问。
  4. 如果您不清楚success()中嵌套函数的范围,我建议您阅读JavaScript中的闭包(一般情况下甚至更好),例如here

    您可以通过以下服务实现目标:

    function($q, $http, /* ... */) {    
        return {
            getData: function() {
                var defer = $q.defer();
                $http.get('/getdata.php', { cache: 'true'})
                .then(function(response) {
                    defer.resolve(response);
                });
    
                return defer.promise;
        };
    }
    

    $http服务很乐意缓存您的回复数据,因此您不必这样做。请注意,您需要从defer红色对象中检索承诺才能使其正常工作。

    控制器是这样的:

    /* omitted */ function($scope, YourService) {
        YourService.getData().then(function(response) {
            $scope.data = response.data;
        });
    }
    

    由于成功折旧,我将成功修改为当时。

答案 1 :(得分:1)

服务应该返回承诺而不是数据。这是异步方式。

首先获取Angular的run方法中的值。对于这个例子,我将它放在$ rootScope中,因为这使得所有控制器中的所有作用域都可以访问它。

AppName.run(['$http', '$rootScope',
    function($http, $rootScope) {
      console.log('Run');
      $http.get('http://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo')
        .success(function(data) {
          $rootScope.resource = data;
          console.log($rootScope.resource);
        });
    }
  ])

除非你将它存放在一些奇怪的地方,否则这不是必需的。

AppName.service('Resource',['$rootScope',
    function($rootScope) {
      return $rootScope.resource;
    }
  ]);

每个范围都将继承$ rootScope中的值(这就是为什么服务确实不是必需的。

AppName.controller('mainController', ['$scope', 'Resource',
  function($scope, Resource) {
    console.log('controller');
    console.log(Resource);
  }
]);

警告!!!在第一个控制器加载后,该值才可用。如果你在控制器中使用它只记得你可以将它绑定到html,但第一次通过控制器代码将不会初始化变量。