角请求忙拦截器

时间:2015-11-02 13:34:03

标签: angularjs angular-http-interceptors

更新

我想我自己解决了。检查my interceptor that I posted as a solution below

ORIGINAL

我想知道是否可以编写一个http拦截器,让拦截器知道请求是如何进行的。

现在,当我想调用我的后端时,我在一个包装器中包装一个$ http调用,该包装器设置我传递的对象的属性:

publ.wrap = function(f, ctrl){

    ctrl.busy   = true;
    ctrl.error  = false;

    return f()

    .then(function(res){

        ctrl.busy   = false;
        ctrl.result = res;

        return res;

    }).catch(function(err){

        ctrl.busy   = false;
        ctrl.error  = err;
        ctrl.result = undefined;

    })

};



publ.login    = function(args, ctrl){

    publ.wrap(function(){

        return $http.post('http://localhost:3001/authenticate', {
            username : args.username,
            password : args.password
        }).then(function(jwt){

            $cookies.put('token', jwt);
        })
    }, ctrl);
};

在这种情况下,我在登录页面控制器中调用login(authArgs, $scope.loginCtrl)。然后我使用loginCtrl.busyloginCtrl.result&我的登录模板中有loginCtrl.error

我非常希望我对后端的每次调用都设置这些属性,并使它们可用于发起请求的视图。

使用这样的包装函数完成工作,但我想知道是否可以使用拦截器完成?我觉得这样可以提供更清晰的请求流程,不需要我在我的服务中明确地包装所有后端调用。

现在我读了httpInterceptors,似乎找不到让它们在用户提供的对象上设置属性的方法。我找到的关闭事件是this article,它有一个示例(时间戳标记(请求和响应拦截器)),它们在requestresponse拦截器阶段向配置对象添加属性。它们没有显示如何访问responseError阶段或调用者控制器中的配置对象。

非常感谢任何帮助:)

2 个答案:

答案 0 :(得分:0)

我使用Angular事件来处理这样的事情 - 例如:

    .controller('parentCtrl', function($scope,$rootScope) {
        $rootScope.$on('loading',function(e,_statusObj.loading) {
            $scope.loading = _statusObj.loading;
            if(!!_statusObj.msg) {
                alert(_statusObj.msg);
            }
        });
    })
    .controller('childCtrl', function($scope,$http) {
        $scope.myAjaxCall = function(_url,_data) {
            $scope.$emit('loading',{ loading: true});
            $http.post(_url,_data).success(function(_response) {
                $scope.$emit('loading',{ loading: false });
            })
            .error(function(_error) {
                $scope.$emit('loading',{
                    loading : false,
                    msg     : _error.message
                });
            });
        }
    });

答案 1 :(得分:0)

我设法让拦截器工作。显然我们可以在所有拦截器阶段访问配置文件:

/******************************************
    SETUP BUSY/ERROR/DATA HTTP INTERCEPTOR
*******************************************/
.config(function($httpProvider){

    $httpProvider.interceptors.push(function($q) {
      return {

        request  : function(config) {

            if(config.ctrl){
                config.ctrl.busy   = true;
                config.ctrl.error  = false;
                config.ctrl.data   = undefined;
            }

            return config;
        },
        response : function(response) {

            if(response.config && response.config.ctrl){
                response.config.ctrl.busy = false;
                response.config.ctrl.data = response.data;
            }

            return response;
        },

        responseError : function(response){

            // note: maybe use a different error message for different kinds of responses?
            var error = response.status + " "+response.statusText+" - "+response.data;

            if(response.config && response.config.ctrl){
                response.config.ctrl.busy = false;
                response.config.ctrl.error = error;
            }

            return $q.reject(error);
        }
      };
    });

})