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);
  }]);
1
GMarsh 18 Aug. 2015 im 22:29

3 Antworten

Beste Antwort

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?

3
Community 23 Mai 2017 im 12:06

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);
}]);
2
wesww 18 Aug. 2015 im 19:34

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

0
Ziad 18 Aug. 2015 im 19:54