1

I have a requirement where I want to retrieve a JSON object from the server. Below are two versions which do not work -

Version 1

app.service("authorization", ['$http', function($http){
  var authMap = [];
  $http.get('/authmap').success(function(data){this.authMap = data});
}]);

Version 2

app.service("authorization", ['$http', function($http){
  var authMap = [];
  $http.get('/authmap').success(function(data){authMap = data});

  var getAuthMap = function(){return authMap};
}]);

In version one I am injecting the service into my controller and accessing it as authorization.authMap, it returns an empty [].

In version two, I am accessing it as authorization.getAuthMap(). Here it gives me an error that no such method is defined on the object ?

What is wrong with both the methods ?

4

3 回答 3

2

只需将变量作为该服务范围的一部分

app.service("authorization", ['$http', function($http){
    var authorizationScope = this;
    authorizationScope.authMap = [];
    $http.get('/authmap').success(function(data){authorizationScope .authMap = data});
}]);

版本 2

app.service("authorization", ['$http', function($http){
    var authorizationScope = this;
    authorizationScope.authMap = [];
    $http.get('/authmap').success(function(data){authorizationScope.authMap = data});

    authorizationScope.getAuthMap = function(){return authorizationScope.authMap};
}]);

这样,当您注入控制器时,您可以访问该变量或函数

function myController($scope, authorization){
    authorization.authMap //this is how you would access the variable here
    authorization.getAuthMap(); //this is how you would access the function
}
于 2012-12-20T15:20:03.790 回答
1
  1. 您应该公开您的功能。
  2. 您需要了解 $http 是一个异步调用。最简单的修复方法是将 $http 承诺返回给您的控制器并在那里解析数据。

所以:

app.service("authorization", ['$http', function($http){
  return {
     getAuthMap : function(){
        return $http.get('/authmap');
     }
  };
}]);

在您的控制器中:

authorization.getAuthMap().then(function(data) {
    $scope.data = data;
});

如果数据很复杂并且应该在您的服务中处理,您可以在您的服务中使用 service $q 并将其承诺返回给您的控制器。这使得服务稍微复杂一些:

app.service("authorization", ['$http', '$q', function($http, $q) {

  var authMap;

  return {
     getAuthMap : function(){
        var deferred = $q.defer();
        var promise = deferred.promise;

        promise.then(function() {
           if (!authMap) {
              $http.get('/authmap').success(function(data) {
                 var changedData = data;
                 // do sth with data
                 authMap = changedData;

                 deferred.resolve(changedData);
              });
           } else {
              deferred.resolve(authMap)
           }
        });
        return deferred.promise;
     }
  };
}]);
于 2012-12-20T12:04:47.320 回答
1

您已经在另一篇文章中询问了版本 1,并在那里得到了回答:Unable to set a class var in $http callback

总结一下:success() 和 error() 方法是在函数上下文(即this)设置为全局上下文(即window)的情况下调用的。因此this.authMap = data将数据存储在 window.authMap 中,而不是在您的服务中。您需要创建一个闭包(通过定义一个局部变量并将其设置为this),然后在 success() 函数中使用该变量:

app.service("authorization", ['$http', function($http){
  this.authMap = [];
  var self = this;
  $http.get('/authmap')
     .success(function(data){
        self.authMap = data
     })
     .error(function(data, status){
        alert('Unable to authorize')
        console.log(status)
     })
}]);

版本 2 有两个问题:

  1. 与版本 1 相同的问题
  2. 您正在使用 service(),因此服务函数的主体需要是 JavaScript 构造函数(因为 Angular 将通过本质上调用new构造函数来实例化服务)。因此,需要在以下位置定义公共属性(包括函数/方法)this
app.service("authorization", ['$http', function($http){
   this.authMap = [];
   this.getAuthMap = function(){ return this.authMap };
   var self = this;
   $http.get('/authmap')
      .success(function(data){
         self.getAuthMap = data
      })
      .error(function(data, status){
         alert('Unable to authorize')
         console.log(status)
      })
}]);

如果您想保持 authMap 私有,请改用 factory():

app.factory("authorization", ['$http', function($http){
   var authMap = [];         // private data
   $http.get('/authmap')
      .success(function(data){
         authMap = data
      })
      .error(function(data, status){
         alert('Unable to authorize')
         console.log(status)
      })
   return {
      getAuthMap: function() { return authMap };
   }
}]);
于 2012-12-20T21:44:26.783 回答