我想设置一个httpInterceptor,以在http请求失败时显示一个常见的模式对话框。我使用https://angular-ui.github.io/bootstrap/作为模态对话框。
我试过
app.config(function ($httpProvider, $uibModal) { ...
但得到错误[$ injector:modulerr]由于以下原因无法实例化模块应用程序: 错误:[$ injector:unpr]未知提供者:$ uibModal
This answer表示配置时只能传递提供商,所以我尝试了
app.config(function ($httpProvider, $uibModalProvider) {
这就是我要打开模态的地方
var modalInstance = $uibModalProvider.open(
我得到的错误是该对象不支持开放的proprty或方法。如何从提供者到模态实例或是否有另一种实现方法?
答案 0 :(得分:9)
请看以下示例:
(function(angular) {
'use strict';
var module = angular.module('app', ['ngAnimate', 'ui.bootstrap']);
module.controller('appController', ['$http', '$log', function($http, $log) {
var vm = this;
vm.sendRequest = sendRequest;
function sendRequest(){
$log.info('Try sending a request');
$http.get('/fake/');
}
}]);
module.controller('ModalInstanceCtrl', ['$scope', '$uibModalInstance', function ($scope, $uibModalInstance) {
$scope.ok = function () {
$uibModalInstance.dismiss('cancel');
};
}]);
module.factory('myHttpInterceptor', ['$log', '$injector', function($log, $injector) {
var interceptor = {
'responseError': function(config) {
$log.info('Request error');
// injecting $uibModal directly cause Circular Dependency error
// following method is a fix of it
$injector.get('$uibModal').open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: 'sm'
});
return config;
}
};
return interceptor;
}]);
module.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('myHttpInterceptor');
}]);
})(window.angular);

body { padding: 20px; }

<!doctype html>
<html lang="en">
<head>
<title>Interceptor & $uibModal sample</title>
<meta charset="UTF-8">
<!-- AngularJS -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.2.4.js"></script>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" >
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" >
</head>
<body ng-app="app">
<div class="panel panel-default" ng-controller="appController as vm">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">Error!</h3>
</div>
<div class="modal-body">
Hello
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok()">OK</button>
</div>
</script>
<div class="panel-heading">
Send failing request
</div>
<div class="panel-body">
<button type="button" class="btn btn-primary" ng-click="vm.sendRequest()">Send request</button>
</div>
</div>
</body>
</html>
&#13;
答案 1 :(得分:5)
使用$injector
服务获取$uibModal
的实例。
app.config(function($httpProvider) {
//To configure an interceptor you have to push a function
//or name of a registered service into the array. The function
//or service is where you call $injector.get();
$httpProvider.interceptors.push(function($injector) {
return {
responseError: function(res) {
var templateUrl = 'http://badurl'; //This can cause infinite recursion!
if (res.config.url === templateUrl) return null; //One way to prevent infinite recursion.
var $uibModal = $injector.get('$uibModal');
var modalInstance = $uibModal.open({
templateUrl: templateUrl
});
return res;
}
}
})
});
但要注意引起无限递归。