更新$ http回调中的服务变量

时间:2014-04-30 20:39:24

标签: angularjs angularjs-service

我正在使用服务将用户数据提供给我的Angular应用程序中的各种控制器。我不知道如何使用$ http服务来更新服务的本地变量(在我的例子中是“this.users”)。我曾经有过无望的尝试。服务器正确响应。

我已经阅读了几篇关于如何在服务中使用$ http来更新控制器范围的优秀文章。最好的是这个:http://sravi-kiran.blogspot.com/2013/03/MovingAjaxCallsToACustomServiceInAngularJS.html。这对我没有帮助,因为它否定了使用服务的好处。主要是,修改一个控制器中的范围不会在应用程序的其余部分进行修改。

这是我到目前为止所做的。

app.service('UserService', ['$http', function($http) {
    this.users = [];

    this.load = function() {
        var promise = $http.get('users.json')
            .success(function(data){
                // this.users is undefined here
                console.log(this.users);
            }
    };

    promise.then(function() {
        // this.users is undefined here
        console.log('this.users');
    });
}]);

非常感谢任何帮助。谢谢。

4 个答案:

答案 0 :(得分:3)

尝试使用

var users = [];

而不是

this.users = [];

看看

console.log(users);

每个案例的输出。

答案 1 :(得分:2)

您的服务定义很奇怪,但如果您有服务,则可以从任何控制器访问它:

app.service('UserService', ['$http', function($http) {
    var users = [];
    this.load = function() {
        var promise = $http.get('users.json')
            .success(function(data){
                // this.users is undefined here
                console.log(users);
                users = data.data;
            }
    };
    return {
        getUsers: function(){
            return users;
        }
    }  
}]);

所以在您的控制器中,您可以使用:

var myUsers = UserService.getUsers();

UPDATE 在这里正确使用服务,您的服务应该返回一个承诺,并且应该在控制器中访问承诺:以下是我给出的另一个答案的示例

// your service should return a promise
app.service('PickerService', [$http', function($http) {
    return {
        getFiles: function(){ 
            return $http.get('files.json'); // this returns a promise, the promise is not executed here
        }
    }
}]);

然后在您的控制器中执行此操作:

PickerService.getFiles().then(function(returnValues){ // the promise is executed here as the return values are here
    $scope.myDirectiveData = returnValues.data;
});

答案 2 :(得分:0)

在您尝试使用它时,它不再具有范围:

app.service('UserService', [$http', function($http) {
var users = [];

this.load = function() {
    var promise = $http.get('users.json')
        .success(function(data){
            console.log(users);
        }
};

    promise.then(function() {
    console.log(users);
    });
}]);

如果将服务的所有局部变量作为属性分配给它,那么每次将服务注入控制器时都会包含它们,这是不好的做法。

答案 3 :(得分:0)

我认为您要求的是一个解决方案,就像定义您的服务一样:

angular.module('app')
  .service('User', function($http, $q) {
    var users = null;
    var deferred = $q.defer()

    return {
      getUsers: function() {
        if(users) {
          deferred.resolve(users);
        } else {

          $http.get('users.json');
            .success(function(result) {
              deferred.resolve(result);
            })
            .error(function(error) {
              deferred.reject(error);
            });
        }
        return deferred.promise;
      }
    };
  });

然后在每个控制器中你必须这样做:

angular.module('app')
  .controller('ACtrl', function($scope, User) {
    User.getUsers().then(function(users) {
      // Same object that's in BCtrl
      $scope.users = users;
    });
  });

angular.module('app')
  .controller('BCtrl', function($scope, User) {
    User.getUsers().then(function(users) {
      // Same object that's in ACtrl
      $scope.users = users;
    });
  });

注意:由于deferred.promise传递给所有控制器的承诺相同,将来执行deferred.resolve(users)会导致您的每个成功回复then次要调用的控制器基本上覆盖旧用户列表。

列表中的所有操作都将在所有控制器中被注意到,因为users数组在此时是一个共享对象。这将仅处理应用程序客户端上的用户列表/每个用户的更新。如果要将更改保留到服务器,则必须向服务添加其他$ http方法以处理用户的CRUD操作。这通常很棘手,我强烈建议您查看ngResource,它负责基本的RESTful操作