Angular jsonp回调只执行一次

时间:2015-11-08 18:53:43

标签: javascript angularjs ajax

配置

(function() {

  angular.module('plunker', ['ngRoute']);

  angular.module('plunker').config(['$routeProvider', moduleConfig]);

  function moduleConfig($routeProvider) {
    $routeProvider
      .when('/home', {
        templateUrl: 'home.html', //url of the template
        controller: 'HomeCtrl', //name of the controller
        controllerAs: 'hCtrl' //how it should be referred in the template
      })
      .when('/profile', {
        templateUrl: 'profile.html', //url of the template
        controller: 'ProfileCtrl', //name of the controller
        controllerAs: 'pCtrl' //how it should be referred in the template
      })
      .otherwise({
        redirectTo: '/home'
      });
  }


  //controllers should be in their own .js files
  angular.module('plunker').controller('HomeCtrl', HomeCtrl);
  angular.module('plunker').controller('ProfileCtrl',['myservice', ProfileCtrl]);

  function HomeCtrl() {
    var hCtrl = this;
    alert('HomeCtrl');
  }

  function ProfileCtrl(myservice) {

    var pCtrl = this;
    myservice.retrive(function(data){
      alert('profile');
    });
  }

})();

为MyService

(function(){

    angular.module('plunker')
        .factory('myservice',myservice);

    myservice.$inject=['$http'];

    function myservice($http) {

        var factory={
            retrive:retrive
        };

        return factory;

        function retrive(callback){

            var url = 'test.json';
            var params = {
                    callback: 'angular.callbacks._0'
                };

            $http.jsonp(url, {params: params}).then(callback);
        }
    }


})();

我为特定页面编写了这个控制器和服务,比如说“/ profile”。配置文件控制器使用具有JSONP请求的服务。当我转到那个页面(“/ profile”)时,一切正常,JSONP回调就会执行。但是当我在“/ profile”之后转到“/ index”并再次回到“/ profile”时,JSONP调用会触发,但控制器中的回调不会被执行。有人可以发现错误

plnkr,代码为http://plnkr.co/edit/fswywkpsH6xl5XU0YplK?p=preview

在此plnkr中,配置文件控制器中的回调仅执行一次

3 个答案:

答案 0 :(得分:1)

它执行了两次但第二次使用404失败。如果添加错误处理函数,可以看到失败:

$http.jsonp(url, {params: params}).then(callback, function() { console.log('I\'ve failed you:', arguments); })

答案 1 :(得分:1)

问题是angular会在内部增加jsonp回调值作为跟踪机制

您必须使用记录的查询字符串?callback=JSON_CALLBACK

JSON_CALLBACK只是$http将在内部替换以下值的占位符:

angular.callbacks._0
angular.callbacks._1
angular.callbacks._2

您的实施问题是您总是返回angular.callbacks._0(),因此下一个期望angular.callbacks._1()的调用没有收到该值,因此会拒绝该请求

将您的服务方式更改为:

  function retrive(callback){

        var url = 'test.json';
        var params = {
                callback: 'JSON_CALLBACK'
            };

        $http.jsonp(url, {params: params}).then(callback ).catch(function(err){
          console.log(err)
        });
    }

在您的演示中,您会在第二个请求中看到err.status404

DEMO

答案 2 :(得分:0)

看看这个修改:http://plnkr.co/edit/5HnXfpjZEzVhtCUjonGa?p=preview

首次检索数据时,您可以在dataLoaded中添加从myservice更改为false的标记true,并在控制器中进行检查:< / p>

//in controller code    
if(!myservice.dataLoaded) {
   myservice.retrive(function(data){
     myservice.dataLoaded = true;
     alert('profile');
   });
 }

//in service code
var factory={
  retrive:retrive,
  dataLoaded: false
};