【问题标题】:Pass data from JSONP callback function to Angular controller将数据从 JSONP 回调函数传递到 Angular 控制器
【发布时间】:2017-02-14 20:06:10
【问题描述】:

我有 JSONP 请求,回调函数在 Angular 控制器之外。如何将该函数中的数据返回给控制器?或者也许有一种方法可以在控制器内部回调函数?

添加 '?callback=JSON_CALLBACK' 不会触发 success 承诺。我认为这是因为 JSONP 响应包含在函数调用中: CBR_XML_Daily_Ru({"日期":"2016-10-06T00:00:00+00:00" ... });

<div ng-controller='myCtrl' ng-app='myApp'>
    <input type=text ng-model='divForCharCode'></input>
    <div id='div1'></div>
</div>

<script>CBR_XML_Daily_Ru = function(data) {
  document.getElementById("div1").innerHTML = data.Valute.EUR.CharCode;

};

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

  function myCtrl($scope,$http) {
      $scope.divForCharCode = ' need to place EUR here!';
    $http.jsonp('https://www.cbr-xml-daily.ru/daily_jsonp.js');
  };</script>

https://plnkr.co/edit/hKdXf7MxAhnU8aMFqPUV

【问题讨论】:

标签: angularjs jsonp


【解决方案1】:

我在搜索和尝试后想出了这个解决方案,在你的情况下这个解决方案比 使用angular.element(....).scope() 的其他解决方案,因为这里我们使用角度服务$window 而在 (angular.element().scope) 我们使用的某些东西可能在某些角度模式下被禁用,check this

CBR_XML_Daily_Ru = function(data) {
  window.angularJsonpCallBackDefindInController(data);

};

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

function myCtrl($scope, $http,$window) {
  var self = this;

  $http.jsonp('https://www.cbr-xml-daily.ru/daily_jsonp.js?callback=JSON_CALLBACK');
  $window.angularJsonpCallBackDefindInController = function (data) {
      //u can do anything here, you are in the controller, and in the same time this function in the window object and get called from anywhere even in jquery 
     self.divForCharCode = data.Valute.EUR.CharCode;
  };
}

您也可以使用这种方式从 jquery "scope" 中执行控制器中的功能:

CBR_XML_Daily_Ru = function(data) {
  angular.element("#controllerDivId").controller().angularJsonpCallBackDefindInController(data);

};

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

function myCtrl($scope, $http,$window) {
  var self = this;

  $http.jsonp('https://www.cbr-xml-daily.ru/daily_jsonp.js?callback=JSON_CALLBACK');
  self.angularJsonpCallBackDefindInController = function (data) {
     self.divForCharCode = data.Valute.EUR.CharCode;
  };
}

这是html(您需要包含jquery才能使用第二种解决方案)

<html>

<head>
  <script src="jquery-3.1.1.min.js"></script>
  <script src="angular.min.js"></script>
  <!--<link rel="stylesheet" href="style.css" />-->
  <script src="jsnopstuff.js"></script>
</head>

<body>
    <div id="controllerDivId" ng-controller='myCtrl as ctrl' ng-app='myApp'>
        <input type=text ng-model='ctrl.divForCharCode'>
        <div id='div1'></div>
    </div>

</body>
</html>

【讨论】:

  • 谢谢,它有效!虽然我仍然怀疑服务器响应的 JSONP 数据格式是否应该与 Angular 一起使用......
  • 欢迎,您查看有关许多 JSONP 服务器不接受角度回调名称 github.com/angular/angular.js/issues/1551 的问题的这一行
【解决方案2】:

我会这样做: 这段代码使用 $q 有一个完整的功能承诺。 希望这会有所帮助

     <div ng-controller='myCtrl' ng-app='myApp'>
        <input type=text ng-model='divForCharCode'></input>
        <div>{{data.Valute.EUR.CharCode}}</div>
    </div>

    <script>

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

          function myCtrl($scope,$http, $q) {
              var self = this;
              self.divForCharCode = ' need to place EUR here!';

              var getDataFromServer = function(){
              var deferred = $q.defer(); // creating a promise
              var url = "https://www.cbr-xml-daily.ru/daily_jsonp.js?callback=JSON_CALLBACK";
              $http.get(url).success(function (data, status, headers,config) {
                deferred.resolve(data);
            }).error(function (data, status, headers, config) {
                //this always gets called
                console.log(status);
                deferred.reject(status);
            });
            return deferred.promise;
          }
           var promise = getDataFromServer();
           promise.then(function(data){
           $scope.data = data;
           });

          };
</script>

【讨论】:

  • 出现错误:XMLHttpRequest 无法加载 cbr-xml-daily.ru/daily_jsonp.js?callback=JSON_CALLBACK。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许访问 Origin '127.0.0.1:8000'。
  • @Anton 发生这种情况是因为您正在尝试从本地托管的服务器访问资源(此处为 jsonp.js 文件)。您尝试访问的服务器不允许 CORS。这通常发生在 webapp 从本地实例运行时。
  • 是远程服务器配置错误还是我的请求有误?我对 cbr-xml-daily.ru 没有任何控制权,而且它不在我的本地网络中。
  • @Anton,我明白了。它只是未配置为接受 CORS 的服务器。正如我之前提到的,在开发阶段完成后,应用程序托管在服务器上或作为混合移动应用程序,这个问题应该不会持续存在。
  • @Anton 或者,作为一种解决方法,您可以使用 chrome 插件来启用 CORS 支持。在 chrome 插件商店中搜索 CORS toggle。在发出任何请求之前启用它。
猜你喜欢
  • 1970-01-01
  • 2018-03-07
  • 2017-03-05
  • 1970-01-01
  • 2015-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-06
相关资源
最近更新 更多