Etwas neu in Angular und Javascript. Ich habe den folgenden Controller geschrieben, verwenden Sie einen Factory-Service, um auf eine lokale JSON-Datei zuzugreifen. Der größte Teil dieses Codes stammt von dieser Beitrag von Dan Wahlin. Ich kann außerhalb der Funktion nicht auf die Variable $ scope.books zugreifen und kann nicht herausfinden, warum. Das console.log innerhalb der Funktion gibt mir das Objekt, nach dem ich suche, aber das außerhalb gibt undefiniert zurück. Was mache ich hier falsch? Vielen Dank.
app.controller('FormController', ['$scope', 'tocFactory', function ($scope, tocFactory) {
$scope.books;
getBooks();
function getBooks() {
tocFactory.getBooks().
success(function(data, status, headers, config) {
$scope.books = data;
console.log($scope.books);
}).
error(function(data, status, headers, config) {
// log error
})
}
console.log($scope.books);
}]);
3 Antworten
Weil Sie einen Ajax erstellen und dann die nächste Codezeile ausführen. Dies bedeutet nicht, dass Sie die Garantie haben, dass Ihre Ajax-Antwort bei Ausführung der nächsten Codezeile bereit ist.
Sie können den Antwortwert immer innerhalb der Erfolgsfunktion von $http
abrufen, die aufgerufen wird, wenn ein Ajax-Aufruf erfolgreich ausgeführt wird.
Lesen Sie hier Wie funktioniert ein asynchroner Anruf?
Eigentlich ist dies keine Frage des Umfangs, sondern des Timings. Die Funktion getBooks wird asynchron ausgeführt. Wenn Ihr Konsolenprotokoll erstellt wird, ist es höchstwahrscheinlich an nichts gebunden. Sie können dies leicht mit Intervallen testen, um zu sehen, wie dies geschieht:
app.controller('FormController', ['$scope', 'tocFactory', function($scope, tocFactory) {
$scope.books;
getBooks();
function getBooks() {
tocFactory.getBooks()
.success(function(data, status, headers, config) {
$scope.books = data;
console.log($scope.books);
})
.error(function(data, status, headers, config) {
// log error
})
}
setInterval(function(){
console.log($scope.books);
}, 1000);
}]);
Sie können den Dienst $ q verwenden, um asynchronen Code mit Versprechungen zu verarbeiten:
app.controller('FormController', ['$scope', '$q', 'tocFactory', function ($scope, $q, tocFactory)
{
var getBooks = function()
{
var deferred = $q.defer();
tocFactory.getBooks().
success( function(data, status, headers, config)
{
$scope.books = data;
deferred.resolve();
} ).
error( function(data, status, headers, config)
{
deferred.reject();
} );
return deferred.promise;
};
getBooks().then( function(res)
{
console.log($scope.books); // success : your data
}, function(res)
{
console.log($scope.books); // error : undefined
} );
console.log($scope.books); // undefined
} ] );
Ich habe diesen Code nicht getestet, aber er sollte funktionieren und Ihnen das Versprechen zeigen. Weitere Informationen zum $ q-Service: https://docs.angularjs.org/api/ng/service/ $ q