AngularJS Service Config value get destroyed on minification

吃可爱长大的小学妹 提交于 2019-12-30 08:02:17

问题


Having some trouble with minification and AngularJS ;-(

I found this jsfiddle "loading" extender for HTTP request, through the AngularJS Wiki page.

It worked great until i published it, and the minification destroys it. I can't find a way to use "inject" on the config, so im kinda lost about what to do.

Original code:

angular.module("app.services", []).config(function($httpProvider) {
  var spinnerFunction;
  $httpProvider.responseInterceptors.push("myHttpInterceptor");
  spinnerFunction = function(data, headersGetter) {
    $("#loader").show();
    return data;
  };
  return $httpProvider.defaults.transformRequest.push(spinnerFunction);
}).factory("myHttpInterceptor", function($q, $window) {
  return function(promise) {
    return promise.then((function(response) {
      $("#loader").hide();
      return response;
    }), function(response) {
      $("#loader").hide();
      return $q.reject(response);
    });
  };
});

Minified code:

angular.module("app.services", []).config(function (a) {
    var b;
    a.responseInterceptors.push("myHttpInterceptor");
    b = function (d, c) {
        $("#loader").show();
        return d
    };
    return a.defaults.transformRequest.push(b)
}).factory("myHttpInterceptor", function (a, b) {
    return function (c) {
        return c.then((function (d) {
            $("#loader").hide();
            return d
        }), function (d) {
            $("#loader").hide();
            return a.reject(d)
        })
    }
});

Which throws the following error: Error: Unknown provider: a from app.services


回答1:


Use inline annotation for defining providers:

angular.module("app.services", [])
  .config(
    [
      '$httpProvider',
      'myHttpInterceptor',
      function($httpProvider, myHttpInterceptor) {
        var spinnerFunction;
        $httpProvider.responseInterceptors.push(myHttpInterceptor);
        spinnerFunction = function(data, headersGetter) {
         $("#loader").show();
         return data;
        };
        return $httpProvider.defaults.transformRequest.push(spinnerFunction);
      }
    ]
  );

And, btw, you should reconsider using jQuery calls inside your configs and factories. Direct DOM manipulation should be handled inside the directives.

For your case, instead of $("#loader").show(); and $("#loader").show(); you should broadcast an event (e.g. $rootScope.$broadcast('loader_show')), and then listen for that event in your custom 'spinner' directive:

HTML:

<div spinner class="loader"></div>

JS:

app.directive('spinner',
    function() {
      return function ($scope, element, attrs) {
        $scope.$on('loader_show', function(){
          element.show();
        });

        $scope.$on('loader_hide', function(){
          element.hide();
        });
      };

    }

  );



回答2:


Just for others in the same situation... I followed @Stewie 's advice, and made this instead, which only uses AngularJS code, no stupid jQuery dependency ;-)

Service:

app.config([
  "$httpProvider", function($httpProvider) {
    var spinnerFunction;
    $httpProvider.responseInterceptors.push("myHttpInterceptor");
    spinnerFunction = function(data, headersGetter) {
      return data;
    };
    return $httpProvider.defaults.transformRequest.push(spinnerFunction);
  }
]).factory("myHttpInterceptor", [
  "$q", "$window", "$rootScope", function($q, $window, $rootScope) {
    return function(promise) {
      $rootScope.$broadcast("loader_show");
      return promise.then((function(response) {
        $rootScope.$broadcast("loader_hide");
        return response;
      }), function(response) {
        $rootScope.$broadcast("loader_hide");
        $rootScope.network_error = true;
        return $q.reject(response);
      });
    };
  }
]);

Directive

app.directive("spinner", function() {
  return function($scope, element, attrs) {
    $scope.$on("loader_show", function() {
      return element.removeClass("hide");
    });
    return $scope.$on("loader_hide", function() {
      return element.addClass("hide");
    });
  };
});



回答3:


As strange as it might seem, you can also use inline annotation where you do the actual .push() to inject your dependencies on $q and $window i.e. instead of pusing a function() into $httpProvider.responseInterceptors you push an array:

app.config(["$httpProvider", function($httpProvider) {
    $httpProvider.responseInterceptors.push(['$q', '$window', function($q, $window) {
        return function(promise) {
            return promise.then(function(response) {
                    $("#loader").hide();
                    return response;
                },
                function(response) {
                    $("#loader").hide();
                    return $q.reject(response);
                });
        };
    }]);
}]);


来源:https://stackoverflow.com/questions/15341588/angularjs-service-config-value-get-destroyed-on-minification

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!