AngularJS AppCtrl ожидание события HTTP для успешного выполнения
Я новичок в AngularJS и нуждаюсь в некоторой помощи, у меня есть "AppCtrl", и оттуда у меня есть вызов HTTP webservice - и мне нужен ответ на вызов webservice, доступный в моих других контроллерах.
angular.module('starter.controllers', [])
.controller('AppCtrl', function($scope, $http) {
$scope.webservice_url = "http://webserviceurl.com/";
$http.get($scope.webservice_url+"?action=get_settings").success(function(data, status, headers, config) {
$scope.stations = data.stations;
});
})
Это прекрасно работает - и я могу получить доступ к $ scope.станции в моих шаблонах - но теперь я хочу получить доступ к $ scope.станции в моем контроллере" PlaylistCtrl", но это не определено : (
.controller('PlaylistCtrl', function($scope, $stateParams) {
console.log($scope.stations); // is undefined :(
})
Как я могу убедиться, что вызов http "сделано" (успех), прежде чем" PlaylistCtrl " загружается ...
4 ответа:
Вы должны превратить http в service / factory, если это возможно
var app = angular.module('plunker', []); app.controller('MainCtrl', function($scope, dataService) { dataService.then(function (data) { $scope.data = data }) }); app.controller('SecondCtrl', function($scope, dataService) { dataService.then(function (data) { $scope.secData = data }) }); app.service('dataService', function ($http, $q){ var defferer = $q.defer() $http.jsonp('http://ip.jsontest.com/?callback=JSON_CALLBACK').success(function (data){ defferer.resolve(data) }) return defferer.promise })
Http://plnkr.co/edit/8k97DngZ8KoFOBPFJG82?p=preview рабочий пример
$scope.stations
ist не неопределен вPlayListCtrl
, потому что вызов HTTP не завершен, но потому чтоPlayListCtrl
имеет другой$scope
, чемAppCtrl
.Вы должны поместить вызов webservice в службу и внедрить эту службу во все контроллеры, которые требуют ее.
В Angular вы не ждете данных перед рендерингом. Вы позволяете ему визуализировать, даже если массив изначально пуст, а затем, как только данные возвращаются, вы визуализируете снова. Angular делает это для поддержания высокого уровня отзывчивости. Это по замыслу, а не то, что вы должны пытаться изменить.
Все, что вам нужно сделать, чтобы исправить вашу неопределенную переменную, - это инициализировать переменнуюstations
scope в вашем контроллере. Хотя он перезаписывается, когда данные возвращаются из службы, это не так важно, потому что angular будет следить за изменениями переменной scope по ссылке и обновлять все представления, когда это произойдет.angular.module('starter.controllers', []) .controller('AppCtrl', function($scope, $http) { $scope.webservice_url = "http://webserviceurl.com/"; $scope.stations = []; $http.get($scope.webservice_url+"?action=get_settings").success(function(data, status, headers, config) { $scope.stations = data.stations; }); })
В вашем внутреннем контроллере, если данные еще не вернулись, $scope.станции будут представлять собой пустой массив:
.controller('PlaylistCtrl', function($scope, $stateParams) { console.log($scope.stations); // is [] $scope.$watch('stations', function(newVal) { alert('data returned!! updating views!'); }); })
Как только данные возвращаются, ссылка на массив в области перезаписывается, вызываются любые обработчики $watch для обновления представления.
// Make a remote request. $http.get('some wonderful URL for a service').success(function (results) { superImportantInfo = results; semaphore = true; }); while (!semaphore) { // We're just waiting. }
Таким образом, вы можете позволить вашему контроллеру подождать, пока он не завершит выполнение контроллера 1, а затем перейти к следующему контроллеру.
Надеюсь на эту помощь!