(Angularjs) как $http.получить данные и сохранить их в сервисе

как вы увидите, я новичок в AngularJS, JS и в веб-разработке вообще =) очень жаль, но я пытаюсь.

Я пытаюсь создать массивную веб-форму (около 200 различных полей) с контроллерами AngularJS. Мне нужен доступ от контроллера к корневому источнику данных. Команда AngularJS просит не делать сервисы только для хранения данных, но я хочу сделать сервис для загрузки и сохранения данных (при запуске.файлы json на a сервер.)

сервис:

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

возврат контроллера не определен. Но утешить.log from service возвращает объект. Я чувствую, что проблема слишком проста, но я не могу найти, как ее решить :( Также я не могу использовать функцию like .getData () от контроллера к службе, потому что он запрашивает данные с сервера каждый раз, когда любой контроллер загружается. У меня есть маршруты в приложении AngularJS с 12-14 контроллерами (полная веб-форма, разделенная на разделы), и я думаю, что это хорошо получить данные из бэкэнда один раз.

P. S. Я думаю, что есть проблема с обещаниями, но когда я пытаюсь использовать такой код:

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

у меня есть объект с разрешения, отклонить и так далее. И действительно не могу понять, что я могу с ним сделать: (

помогите мне получить данные в контроллере:)

2 ответов


ваш код не работает, потому что обратный вызов, который вы предоставили success() в вашей службе вызывается асинхронно; после того, как ваша служба вернулась, то есть:

последовательность выглядит так:

  1. на function в MasterData выполняется. The $http.get запрос запускается и прилагается обратный вызов promise. responseData ссылается в этом обратном вызове (он же. "закрыто").
  2. функция возвращается из службы на контроллер. responseData не был установлен еще, что не останавливает функцию родительской области от возврата.
  3. $http.get успешно и responseData установлен в службе, однако недоступен для контроллера.

если область видимости вложенной функции в success() вам непонятно, я бы рекомендовал прочитать о закрытиях в JavaScript (или даже лучше, в целом), например здесь.

вы можете достигнуть вашей цели с обслуживанием как это:

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

поскольку успех обесценивается, я изменил успех на то.


службы должны возвращать обещание, а не данные. Это асинхронный способ.

сначала извлеките значение в методе выполнения Angular. Для этого примера я поместил его в $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, но первый проход через код контроллера еще не инициализировал переменную.