我应该使用Service或Factory作为我的$ http拦截器

时间:2014-11-16 16:50:28

标签: angularjs typescript

我需要为$ http服务实现一个拦截器。我尝试了使用工厂和服务的2个实现,它们都可以正常工作。这是类型脚本中的实现:

服务

 export class AuthInterceptorService {

    private _authService:Services.IAuthService;

    static $inject = ['$q', '$location', '$injector'];  

    constructor(private $q: ng.IQService, private $location: ng.ILocationService, private $injector: ng.auto.IInjectorService) {

    }

    private getAuthService = (): Services.IAuthService=> {
        if (this._authService == null) {
            this._authService = this.$injector.get('authService');
        }
        return this._authService;
    }

    public request = (config: ng.IRequestConfig) => {
        config.headers = config.headers || {};
        var authData = this.getAuthService().authData;
        if (authData) {
            config.headers.Authorization = 'Bearer ' + authData.token;
        }
        return config;
    }

    public responseError = (rejection)=> {
        if (rejection.status === 401) {
            this.getAuthService().logOut();
        }
        return this.$q.reject(rejection);
    }
}

在app init中:

.service('authInterceptorService', Services.AuthInterceptorService)

工厂

export function AuthInterceptorFactory($q: ng.IQService, $injector: ng.auto.IInjectorService) {

    return {
        request: (config: ng.IRequestConfig)=> {
            config.headers = config.headers || {};
            var authData = $injector.get('authService').authData;
            if (authData) {
                config.headers.Authorization = 'Bearer ' + authData.token;
            }
            return config;
        },

        responseError: (rejection)=> {
            if (rejection.status === 401) {
                $injector.get('authService').logOut();
            }
            return $q.reject(rejection);
        }
    };
}

在app init中:

.factory('authInterceptorFactory', ['$q', '$injector', Services.AuthInterceptorFactory])

然后关于拦截器的配置:

.config(['$httpProvider', ($httpProvider:ng.IHttpProvider) => {
    $httpProvider.interceptors.push('authInterceptorxxxxx');
}])

正如您所看到的,我正在使用服务位置模式注入依赖项(使用$ injector),这是为了避免循环依赖,因为注入的服务依赖于$ http。

正如我所说他们都工作,我更喜欢Service版本,因为它允许我缓存依赖服务'authService'的注入,它在工厂风格中得到解决并在每个请求上一直注入。使用服务实现有什么问题吗?在Angular docs中,他们提到你应该使用工厂。

1 个答案:

答案 0 :(得分:2)

为HttpInterceptor使用服务没有任何问题。 }只需要injector.get来解决它,所以使用服务就可以了。

来自来源$injector.get(interceptorFactory) https://github.com/angular/angular.js/blob/6f19a6fd33ab72d3908e3418fba47ee8e1598fa6/src/ng/http.js#L207-L210

 forEach(interceptorFactories, function(interceptorFactory) {
      reversedInterceptors.unshift(isString(interceptorFactory)
          ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory));
    });