在Angular中,在闭包中引用服务属性/方法最合适的方式是什么?

What's the most appropriate way to reference a service property/method inside a closure in Angular?

本文关键字:方式 是什么 Angular 闭包 引用 属性 服务 方法      更新时间:2023-09-26

我正在创建一个Angular服务,我想知道下面这个场景的最佳实践是什么。

authModule.service('authService', 
    function($http, $sessionStorage, $window, $q, $rootScope) {
        this.variable1 = true;
        this.processVariable = function () {
            return $http({...}).then(function(response) {
            variable1 = response.data; 
            //line above this will throw an error because it's not scoped
        }, function (reason) {
        });
    }
} 

如果我使用Knockout,我会在variable1声明上方添加var self = this;,然后使用self.variable1而不是variable1

使用var self = this;是最佳实践,还是在使用Angular时有不同的首选方法?

你可以把它定义为一个变量

 var variable1 = true;

如果你想设置它为实例属性this.variable1 = true;

那么你可以这样做:-

      var _that = this; 
      this.processVariable = function () {
        return $http({...}).then(function(response) {
        _that.variable1 = response.data; 
        //line above this will throw an error because it's not scoped
    }, function (reason) {
    });

原因是当你在$http承诺的回调中时,this不会作用域到你的服务实例。你还可以使用bind来更改回调中的上下文,使其作用域为服务实例。

但是当调用连续进行时可能会出现问题(并且因为服务是一个单例,它将是相同的this.variable1,您将修改或覆盖最后返回的调用),不确定您正在尝试做什么,但最好的方法是从服务中的承诺回调返回数据。

authModule.service('authService', 
    function($http, $sessionStorage, $window, $q, $rootScope) {
      this.processVariable = function () {
        return $http({...}).then(function(response) {
            return response.data; 
            //line above this will throw an error because it's not scoped
        }, function (reason) {
            $q.reject(reason)
        });
    }
} 

PSL这很好,但正如angular建议的那样,你应该在数组中调用依赖项,而不是函数参数,并且还需要返回服务以返回承诺。而最小化JavaScript代码依赖关系将保持不变。

authModule.service('authService', ['$http', '$sessionStorage', '$window', '$q', '$rootScope', 
function(http, sessionStorage, window, q, rootScope) {
    return this.processVariable = function() {
        return http({...
        }).then(function(response) {
            return response.data;
            //line above this will throw an error because it's not scoped
        }, function(reason) {
            return q.reject(reason)
        });
    }
}]);