6

Ich bin ganz neu in AngularJS und brauche etwas Hilfe, ich habe eine "AppCtrl" und von dort habe ich einen HTTP-Webservice-Aufruf - und benötigen die Webservice-Anruf-Antwort in meinem anderen Controller .AngularJS AppCtrl warte auf HTTP-Ereignis zum Erfolg

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

Dies funktioniert - und ich kann die $ scope.stations in meine Vorlagen zugreifen - aber jetzt möchte ich in meinem „PlaylistCtrl“ Controller die $ scope.stations zugreifen, aber dies ist nicht definiert :(

.controller('PlaylistCtrl', function($scope, $stateParams) { 
    console.log($scope.stations); // is undefined :(
}) 

Wie kann ich sicherstellen, dass der HTTP-Aufruf ist „done“ (Erfolg) vor dem „PlaylistCtrl“ geladen wird ...

Antwort

10

sollten Sie den http in Dienst/Werk wenden, wenn möglich

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 Beispiel

2

$scope.stations ist nicht undefiniert in PlayListCtrl, weil der HTTP-Aufruf nicht beendet ist, sondern weil PlayListCtrl hat eine andere $scope als AppCtrl.

Sie sollten den Webservice-Anruf in einen Dienst aufnehmen und diesen Dienst in alle Controller einspeisen, die ihn benötigen.

+0

Dank Arbeit, der Sinn machen - aber ich weiß nicht, wie man einen Service in Anspruch nehmen und wie es zu injizieren - Hast du ein Beispiel und so? ;) – pkdkk

-4

So können Sie Ihren Controller warten lassen, bis die Ausführung von Controller 1 beendet ist und bevor Sie zum nächsten Controller wechseln.

Hoffe diese Hilfe!

+0

Maby ich kleine hacky;) .. Aber ich werde versuchen .- – pkdkk

1

In Angular warten Sie nicht auf Daten vor dem Rendern. Sie lassen es rendern, auch wenn das Array anfänglich leer ist. Wenn die Daten zurückgegeben sind, rendern Sie erneut. Angular tut dies, um eine hohe Reaktionsfähigkeit aufrechtzuerhalten. Es ist von Entwurf, und nicht etwas, das Sie versuchen sollten, zu ändern.

Sie müssen lediglich die Bereichsvariable stations in Ihrem Controller initialisieren, um Ihre undefinierte Variable zu reparieren. Obwohl es überschrieben wird, wenn die Daten von Ihrem Dienst zurückgegeben werden, spielt es keine Rolle, da angle nach Änderungen an der Bereichsvariablen nach Referenz sucht und alle Ansichten aktualisiert, wenn dies der Fall ist.

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

In Ihrem inneren Controller, wenn die Daten noch nicht zurückgekehrt ist, wird $ scope.stations ein leeres Array sein:

.controller('PlaylistCtrl', function($scope, $stateParams) { 
    console.log($scope.stations); // is [] 
    $scope.$watch('stations', function(newVal) { 
     alert('data returned!! updating views!'); 

    }); 
}) 

Sobald die Daten zurückgibt, über den Umfang der Array-Referenz ist überschrieben, werden alle $ watch-Handler aufgerufen, um die Ansicht zu aktualisieren.