如何处理带有ajax和文件上传的加载微调器的$ broadcast

时间:2014-10-30 12:47:27

标签: javascript angularjs

我正在使用this GIST中找到的一些代码:

.factory('httpInterceptor', function ($q, $rootScope, $log) {
    var numLoadings = 0;
    return {
        request: function (config) {
            numLoadings++;

            // Show loader
            $rootScope.$broadcast("loader_show");
            return config || $q.when(config)
        },
        response: function (response) {

            if ((--numLoadings) === 0) {
                // Hide loader
                $rootScope.$broadcast("loader_hide");
            }

            return response || $q.when(response);
        },
        responseError: function (response) {
            if (!(--numLoadings)) {
                // Hide loader
                $rootScope.$broadcast("loader_hide");
            }
            return $q.reject(response);
        }
    };
})
.config(function ($httpProvider) {
    $httpProvider.interceptors.push('httpInterceptor');
});

它经过了一些修改,以满足我的需求,但它基本上做了同样的事情。

我有一个表单提交iframe上传文件(由于浏览器支持,我不能使用AJAX)。我在开始上传之前使用以下代码来打开加载微调器:

$rootScope.$broadcast('loader_show');

并类似地将此代码与'loader_hide'一起使用以隐藏微调器。

问题在于,在上传大型(~20MB)文件期间,保持活动的AJAX调用会关闭微调器,因为在文件上载过程中numLoadings部分没有递增/递减。有没有办法在提交表单的控制器中访问httpInterceptor来处理这个问题?

1 个答案:

答案 0 :(得分:0)

对于AngularJS相当缺乏经验,我没有意识到httpInterceptor在这种情况下只是一个连接到$httpProvider作为拦截器的服务。一旦我掌握了这个概念,就很容易。

在提交表单的控制器中,只需像这样连接服务并拨打request

.controller('ConfigurationUploadFileCtrl', function($scope, httpInterceptor) {
  // this is called with ng-click on a button
  $scope.processForm = function(form) {
    httpInterceptor.request(); // turns on spinner
    // do stuff to submit the form...
  };
}

在回调中(从iframe响应中调用):

function processFileUpload(data) {
  // do stuff to handle returned data, and then...
  angular.element('#configFileUploadForm')
         .injector().get('httpInterceptor').response(); // turns off spinner
}

希望这有助于其他人!