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 6

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, а затем перейти к следующему контроллеру.

Надеюсь на эту помощь!