http.jsonp和javascript中的回调

时间:2015-01-21 01:30:55

标签: javascript angularjs

我正在研究一种考虑AWS实例成本的计算器。我从亚马逊上的.js文件中提取数据,我想将其读入一个对象,但我一直收到错误“未捕获的ReferenceError:回调未定义”..这是我的.js文件。

(function() {
  var app = angular.module('formExample', []);

  var ExampleController = function($scope, $http) {
    $scope.master = {};

    $scope.update = function(user) {
      $scope.master = angular.copy(user);
      $scope.GetAws();
    };

    $scope.reset = function() {
      $scope.user = "";
    };

    function callback(data) {
      $scope.aws = data;
    }

    $scope.GetAws = function() {
      var url = "http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js?callback=callback";
      $http.jsonp(url);
    };

    $scope.reset();
  };
  app.controller('ExampleController', ['$scope', '$http', ExampleController]);
}());

3 个答案:

答案 0 :(得分:2)

你正在使用的aws链接支持jsonp很奇怪,但它不需要自定义回调函数名称。 (至少您可以查找他们正在查找的查询字符串是否为callback)。当我们提供callback=JSON_CALLBACK时,angular会将其转换为angular.callbacks_x,它会被角度临时全局公开以处理请求并相应地解析承诺。但是为此,端点必须采用回调参数并将响应包装在相同的字符串和函数调用中。但是,这个端点似乎没有考虑它,即使没有任何回调,它也会自动包装到默认的callback函数调用中。因此,您需要注入$window(正确的DI方式)对象并将callback函数设置为它,并且?callback=callback无关紧要。

  var ExampleController = function($scope, $http, $window) {
    $scope.master = {};

    //....

    $window.callback = function(data) {
      $scope.aws = data;
    }

    $scope.GetAws = function() {
      var url = "http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js?callback=callback";
      $http.jsonp(url);
    };

    $scope.reset();
   };

   app.controller('ExampleController', ['$scope', '$http', '$window', ExampleController]);

<强> Plnkr

答案 1 :(得分:1)

这是因为AWS脚本正在寻找一个名为&#34; callback&#34;的函数。在全球范围内(Angular之外)。由于您的功能在另一个(IIFE)功能的范围内,因此无法访问。

我在这种情况下所做的只是将功能放在全局范围内。

如果应用程序需要在Angular之前加载某些API,并且有类似于你的情况的回调,我已经完成了以下操作,手动引导Angular:

<强>的index.html

<script src="http://www.example.com/api?callback=myCallbackFunction"></script>

<强> app.js

// callback function, in global (window) scope
function myCallbackFunction() {

  // manually bootstrap Angular
  angular.element(document).ready(function() {
    angular.bootstrap(document, ['myApp']);
  });

}


// your IIFE
(function() {

})();

答案 2 :(得分:1)

注意callback应在window范围内设置。 所以,一个解决方案就像:

$scope.reset = function() {
  $scope.user = "";
};

window.callback = function(data) {
  $scope.aws = data;
}

$scope.GetAws = function() {
  var url = "http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js?callback=callback";
  $http.jsonp(url);
};