2013-02-03 28 views
9

Tôi đang cố gắng sử dụng $ http, nhưng tại sao nó trả về kết quả rỗng?

angular.module('myApp') 
.factory('sender', function($http) { 
    var newData = null; 
    $http.get('test.html') 
     .success(function(data) { 
      newData = data; 
      console.log(newData) 
     }) 
     .error(function() { 
      newData = 'error'; 
     }); 
    console.log(newData) 
    return newData 
}) 

Bàn điều khiển nói: http://screencast.com/t/vBGkl2sThBd4. Tại sao newData của tôi đầu tiên là null và sau đó được xác định? Làm thế nào để làm điều đó một cách chính xác?

+0

Này, nếu câu trả lời của tôi là những gì bạn đang theo đuổi xin vui lòng chấp nhận nó vì vậy nó không ở lại mở mãi mãi . Chúc mừng! – GFoley83

Trả lời

5

Mã JavaScript này không đồng bộ.

console.log(newData) 
return newData 

được thực hiện trước những gì bên trong success

newData = data; 
console.log(newData) 

Vì vậy, vào thời điểm đầu tiên, newData là null (bạn đặt nó vào được null)

Và khi phản ứng http được trả lại (bên trong thành công), newData nhận giá trị mới của nó.

Điều này rất phổ biến trong Javascript, bạn nên thực hiện tất cả công việc của mình bên trong success.

+0

Ok, tôi hiểu. Cảm ơn bạn! – Ilia

20

Như YardenST đã nói, $http là không đồng bộ, do đó bạn cần đảm bảo rằng tất cả các hàm hoặc logic hiển thị phụ thuộc vào dữ liệu được trả về bởi $http.get() của bạn, được xử lý tương ứng. Một cách để thực hiện điều này là để tận dụng các "lời hứa" mà $http lợi nhuận:

Plunkr Demo

var myApp = angular.module('myApp', []); 

myApp.factory('AvengersService', function ($http) { 

    var AvengersService = { 
     getCast: function() { 
      // $http returns a 'promise' 
      return $http.get("avengers.json").then(function (response) { 
       return response.data; 
      }); 
     } 
    }; 

    return AvengersService; 
}); 


myApp.controller('AvengersCtrl', function($scope, $http, $log, AvengersService) { 
    // Assign service to scope if you'd like to be able call it from your view also 
    $scope.avengers = AvengersService; 

    // Call the async method and then do stuff with what is returned inside the function 
    AvengersService.getCast().then(function (asyncCastData) { 
      $scope.avengers.cast = asyncCastData; 
    }); 

    // We can also use $watch to keep an eye out for when $scope.avengers.cast gets populated 
    $scope.$watch('avengers.cast', function (cast) { 
     // When $scope.avengers.cast has data, then run these functions 
     if (angular.isDefined(cast)) {   
      $log.info("$scope.avengers.cast has data"); 
     } 
    }); 
}); 
+0

Cảm ơn bạn rất nhiều! – Ilia

+0

Câu trả lời hay !! Tôi sẽ thêm nó vào blog của mình !! :) –

+0

@ sk8terboi87 ツ Sau đó nhấp vào cuộc bỏ phiếu đó; đó là những gì nó cho! :) – GFoley83

Các vấn đề liên quan