简体   繁体   English

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

[英](Angularjs) How to $http.get data and store it in service

As you will see i'm new in AngularJS, JS and in web development at all =) really sorry for that but i try to. 正如你将看到我是AngularJS,JS和web开发中的新手=)真的很抱歉,但我试着。

I try to build a massive webform (about 200 different fields) with AngularJS controllers. 我尝试用AngularJS控制器构建一个庞大的webform(大约200个不同的字段)。 I need access from controller to root data source. 我需要从控制器访问根数据源。 AngularJS team ask do not make Services just for storing data, but i want to make service for load and save data (at start into .json files on a server). AngularJS团队要求不要仅仅为了存储数据而提供服务,但我想为加载和保存数据提供服务(在服务器上启动.json文件)。

Service: 服务:

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;

}]);

Controller: 控制器:

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

Controller return undefined. 控制器返回undefined。 But console.log from service returns the object. 但是来自服务的console.log返回对象。 I feel that the problem is too easy, but i can't find how to solve it :( Also i can't use function like .getData() from controller to service because it ask the data from server each time any controller loads. I have the routes in AngularJS app with 12-14 controllers (full webform divided by sections) and i think it is good to get the data from backend once. 我觉得这个问题太容易了,但我找不到如何解决它:(我也不能使用像.getData()这样的函数从控制器到服务,因为每次控制器加载时它都会从服务器询问数据。我在AngularJS应用程序中有12-14个控制器的路由(完整的webform除以部分),我认为从后端获取数据一次是好的。

PS I think there is problem with promises, but when i try to use code like this: PS我觉得承诺有问题,但是当我尝试使用这样的代码时:

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

I've got object with resolve, reject and so on. 我有决心,拒绝等对象。 And really can't understand what can i do with it :( 真的无法理解我能用它做什么:(

Help me to get the data in controller :) 帮我在控制器中获取数据:)

Your code doesn't work, because the callback you supplied to success() in your service is called asynchronously; 您的代码不起作用,因为您在服务中提供给success()的回调是异步调用的; after your service has returned, that is: 服务返回后,即:

The sequence is like this: 顺序是这样的:

  1. The function in MasterData is run. 运行MasterData中的function The $http.get request is launched and attached the promise callback. 启动$http.get请求并附加promise回调。 responseData is referenced in this callback (aka. "closed over"). responseData在此回调中被引用(又名“已关闭”)。
  2. The function returns from the service to your controller. 该函数从服务返回到您的控制器。 responseData has not been set yet, which doesn't stop the parent scope function from returning. 尚未设置responseData ,这不会阻止父作用域函数返回。
  3. $http.get succeeds and responseData is set in the service however unreachable for the controller. $http.get成功,并在服务中设置responseData ,但控制器无法访问。

If the scoping of the nested function in success() is not clear to you, I'd recommend reading about closures in JavaScript (or even better, in general), for example here . 如果你不清楚success()嵌套函数的范围,我建议你阅读JavaScript中的闭包(或者更好,一般来说),例如这里

You can achieve your goal with a service like this: 您可以通过以下服务实现目标:

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;
    };
}

The $http service will happily cache your response data, so you don't have to. $http服务很乐意缓存您的响应数据,因此您不必这样做。 Note that you need to retrieve the promise from your defer red object to make this work. 请注意,您需要从defer红色对象中检索承诺以使其工作。

The controller is like this: 控制器是这样的:

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

Since success is depreciated, I modified success to then. 由于成功折旧,我改为成功。

Services should return the promise rather than the data. 服务应该返回承诺而不是数据。 This is the asynchronous way. 这是异步方式。

First fetch the value in the Angular's run method. 首先获取Angular的run方法中的值。 For this example I put it in the $rootScope since that makes it accessible to all scopes in all controllers. 对于这个例子,我将它放在$ 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);
        });
    }
  ])

This is not really necessary unless you store it in some weird place. 除非你把它存放在一些奇怪的地方,否则这不是必需的。

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

Every scope will inherit the values in the $rootScope (thats why the service really isn't necessary. 每个范围都将继承$ rootScope中的值(这就是为什么服务确实不是必需的。

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

Warning!!! 警告!!! This value will not be available until after the first controller loads. 在第一个控制器加载后,该值才可用。 If you use it in the controller just remember that you can bind it to html but the first pass through the controller code will not have initialized the variable yet. 如果你在控制器中使用它只记得你可以将它绑定到html,但第一次通过控制器代码将不会初始化变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM