将http拦截器写为类

时间:2013-12-27 10:02:23

标签: javascript angularjs typescript

我在使用纯TypeScript编写角度http拦截器时遇到了麻烦。我试图转换的代码如下:

.config(['$httpProvider', function ($httpProvider) {

    var interceptor = ['$rootScope', '$q', 'httpBuffer', function ($rootScope, $q, httpBuffer) {
        function success(response) {
            return response;
        }

        function error(response) {
            if (response.status === 401 && !response.config.ignoreAuthModule) {
                var deferred = $q.defer();
                httpBuffer.append(response.config, deferred);
                $rootScope.$broadcast('event:auth-loginRequired', response);
                return deferred.promise;
            }
            // otherwise, default behaviour
            return $q.reject(response);
        }

        return function (promise) {
            return promise.then(success, error);
        };

    }];
    $httpProvider.responseInterceptors.push(interceptor);
}])

第一部分是清楚的,编写一个带有构造函数的类,该构造函数接受三个依赖项$rootScope$qhttpBuffer。还要编写两个私有方法successresponse

class MyInterceptorClass {
    constructor(private $rootScope: ng.IRootScopeService, private $q: ng.IQService, private httpBuffer: HttpBuffer) {
    }

    private success(response: ng.IHttpPromiseCallbackArg<any>): ng.IHttpPromiseCallbackArg<any> {
        return response;
    }

    private error(response: ng.IHttpPromiseCallbackArg<any>): ng.IHttpPromiseCallbackArg<any> {
        if (response.status == 401 && !((<any>response.config).ignoreAuthModule)) {
            var deferred = this.$q.defer();
            this.httpBuffer.append(response.config, deferred);
            this.$rootScope.$broadcast('event:auth-loginRequired', response);

            return deferred.promise;
        }

        // Otherwise, default behavior
        return this.$q.reject(response);
    }
}

拦截器的注册也应该清楚:

.config(['$httpProvider', ($httpProvider: ng.IHttpProvider)=> {
    $httpProvider.responseInterceptors.push(['$rootScope', '$q', 'httpBuffer', MyInterceptorClass]);
}]);

我遇到的麻烦是原始JavaScript的最后一部分,即匿名函数的返回值。我如何在TypeScript中创建它?据我所知,这将是TypeScript中的无名方法,但这是不可能的。

5 个答案:

答案 0 :(得分:6)

配置设置如下

    .config(['$httpProvider', function ($httpProvider: ng.IHttpProvider) {
        $httpProvider.interceptors.push(AuthenticationInterceptor.Factory);
    }])

您的实际课程应如下所示

module Common.Security {
'use strict';

export class AuthenticationInterceptor {

    public static Factory($q: ng.IQService) {
        return new AuthenticationInterceptor($q);
    }

    constructor(private $q: ng.IQService) {
    }

    //Method name should be exactly "response" - http://docs.angularjs.org/api/ng/service/$http
    public response(response) {
        console.log(response);
        return response || this.$q.when(response);
    }

    public responseError(rejection) {
        console.log(rejection.status);
        if (rejection.status === 401) {
        }
        // Otherwise, default behavior
        return this.$q.reject(rejection);
    }
}

答案 1 :(得分:6)

这就是我如何将httpinterceptor编写为类

module services {

export class ErrorHttpInterceptor {
    public $log:ng.ILogService;
    public $injector:ng.auto.IInjectorService;

    public responseError = (_rejection)=>{
       //handle error here
    };
    public request = (config)=>{
        config.withCredentials = true;
        return config;
    };
    public requestError = (rejection)=>{
        var $q:ng.IQService = this.$injector.get("$q");
        this.$log.log("requestError", rejection);
        return $q.reject(rejection);
    };
    static $inject = ['$injector', '$rootScope', '$q', '$window'];
    constructor($injector:ng.auto.IInjectorService, public $rootScope, public $q, public $window){
        this.$log = $injector.get('$log');
        this.$injector = $injector;
    }
  }
}

注册

 var app =angular.module('foo',[]);
 app.config(['$httpProvider', (_$httpProvider:ng.IHttpProvider)=>{
    _$httpProvider.interceptors.push('ErrorHttpInterceptor');

}]);

答案 2 :(得分:4)

你需要这样做: 公众回应=(响应)=&gt; {}

public responseError =(rejection)=&gt; {}

因为以其他方式你的'this'将是未定义的。 要理解为什么需要这个:https://www.youtube.com/watch?v=tvocUcbCupA&hd=1

答案 3 :(得分:4)

配置设置如下

    .config(['$httpProvider', function ($httpProvider: ng.IHttpProvider) {
        $httpProvider.interceptors.push(AuthenticationInterceptor.Factory);
    }])

您的实际课程应如下所示

module Common {
'use strict';

export class AuthenticationInterceptor {

    private static _instance: AuthenticationInterceptor;

    public static Factory($q: ng.IQService) {
        AuthenticationInterceptor._instance = new AuthenticationInterceptor($q);

        return AuthenticationInterceptor._instance;
    }

    constructor(private $q: ng.IQService) {
    }

    //Method name should be exactly "response" - http://docs.angularjs.org/api/ng/service/$http
    public response(response) {
        var self = Common.AuthenticationInterceptor._instance;

        console.log(response);
        return response || self.$q.when(response);
    }

    public responseError(rejection) {
        var self = Common.AuthenticationInterceptor._instance;

        console.log(rejection.status);
        if (rejection.status === 401) {
        }

        // Otherwise, default behavior
        return self.$q.reject(rejection);
    }
}

有必要使用完整命名空间获取类的实例,因为当从Angular' 接收回调时,此 '未定义。

答案 4 :(得分:2)

按名称注册:$httpProvider.interceptors.push('myInterceptorClass');

然后确保您的课程也被注册为服务:

yourApp.service('myInterceptorClass',MyInterceptorClass)