$success call back function from AngularJS

2020-02-14 16:46发布

问题:

I am calling the controller to get the API value. How do I pass the array outside of the $http method?

I need to pass an array, pa[], to the $scope.myData = pa;.

First, console.log(pa) prints the value [10,20,30,40].

Second, console.log(pa) empties array[].

JavaScript

function Ctrl($scope, $http) {
    var url = "https://spreadsheets.google.com/feeds/list/0AsXjbsnPIu06dGswZUV4WX/values?alt=json-in-script&callback=angular.callbacks._0";
    var pa = [];
    $http({
        method: 'JSONP',
        url: url
    }).success(function (data) {

        for (i = 0; i < data.feed.entry.length; i++) {
            var entry = data.feed.entry[i];
            pa.push(entry.gsx$productivity.$t);
            console.log(pa); //[10,20,30,40,50]
        }
    });

    console.log(pa) // [] empty array

    $scope.myData = pa;
}

How do I get the array outside of the $success callback function?

回答1:

This code is asynchronous. pa is assigned to $scope.myData before the $http service has had a chance to get the value from your API call.

You need to use the $q service promise library to control the flow of your code. Something like this:

function Ctrl($scope, $http, $q) {
  var url = "https://spreadsheets.google.com/feeds/list/0AsXjbsnPIu06dGswZUV4WX/values?alt=json-in-script&callback=angular.callbacks._0";
  var pa = [];
  var paPromise = $q.defer()

  $http({
    method: 'JSONP',
    url: url
  }).success(function(data) {

      for (i = 0; i < data.feed.entry.length; i++) {
        var entry = data.feed.entry[i];
        pa.push(entry.gsx$productivity.$t);
        console.log(pa); //[10,20,30,40,50]
      }
      paPromise.resolve(pa)
    });

  $scope.myData = paPromise.promise;
}

Here, we inject the $q service and instantiate a variable paPromise using it. Next, we give this promise to $scope.myData. Once the promise gets resolved inside the $http success method, AngularJS will notify your $scope and update the value and it'll be reflected on your template/DOM.



回答2:

This really doesn't make a lot of sense. It should just be like this:

$scope.myData = [];
$http({
    method: 'JSONP',
    url: url
}).success(function (data) {

    for (i = 0; i < data.feed.entry.length; i++) {
        var entry = data.feed.entry[i];
        $scope.myData.push(entry.gsx$productivity.$t);
        console.log(pa); //[10,20,30,40,50]
    }
});

Since pa was set inside of the controller function, it doesn't buy you anything to declare it and then set $scope.myData equal to pa. That's just asking for trouble.



回答3:

If you prefer jQuery Ajax, use the extend function to return the success data outside,

$(function(){
    $.extend({
        returnData: function(url) {
            var result = null;
            var pa = [];
            $.ajax({
                url: url,
                type: 'get',
                dataType: 'jsonp',
                async: false,
                success: function(data) {
                    for (i = 0; i < data.feed.entry.length; i++) {
                        var entry = data.feed.entry[i];
                        pa.push(entry.gsx$productivity.$t);
                    }
                    result = pa;
                }
            });
            return result;
        }
    });
});
finaldata = $.returnData('https://spreadsheets.google.com/feeds/list/0AsXjbsnPIu06dGswZUV4WX/values?alt=json-in-script&callback=angular.callbacks._0');
console.log(finaldata);