有人可以帮助我理解以下异常处理服务。
angular.module('services.exceptionHandler', ['services.i18nNotifications']);
angular.module('services.exceptionHandler').factory('exceptionHandlerFactory', ['$injector', function($injector) {
return function($delegate) {
return function (exception, cause) {
// Lazy load notifications to get around circular dependency
//Circular dependency: $rootScope <- notifications <- i18nNotifications <- $exceptionHandler
var i18nNotifications = $injector.get('i18nNotifications');
// Pass through to original handler
$delegate(exception, cause);
// Push a notification error
i18nNotifications.pushForCurrentRoute('error.fatal', 'error', {}, {
exception:exception,
cause:cause
});
};
};
}]);
angular.module('services.exceptionHandler').config(['$provide', function($provide) {
$provide.decorator('$exceptionHandler', ['$delegate', 'exceptionHandlerFactory', function ($delegate, exceptionHandlerFactory) {
return exceptionHandlerFactory($delegate);
}]);
}]);
答案 0 :(得分:4)
您所看到的是服务拦截。当您从配置块中调用$ provide时,您可以使用“decorator”方法来拦截服务。装饰的第一个参数将是您希望拦截的服务。在这种情况下,调用是要求Angular附带的原始$ exceptionHandler服务。
第二个参数是一个依赖项数组,其中包含一个使用依赖项的函数。因此,换句话说,依赖注入将解析依赖项列表并将其传递给作为数组中最后一个元素的函数。
在decorator的情况下,特殊依赖项$ delegate表示您正在修改的服务。如果你这样做了:
$provide.decorator('$exceptionHandler', ['$delegate', function($delegate) {
return $delegate;
}]);
您基本上只需要获取异常处理程序服务并将其传回。
相反,调用将进入异常处理程序工厂。它正在使用工厂来推迟从services.i18nNotifications模块加载依赖项,大概是因为它也会引用$ exceptionHandler。 $ injector允许延迟加载引用,因此$ injector.get()正在获取注册为i18Notifications的内容。
正在发生的是返回一个与内置$ exceptionHandler具有完全相同签名的函数:
fn(exception, cause)
该函数调用原始处理程序:
$delegate(exception, cause)
然后添加自己的行为,看起来它正在创建一个带有异常和原因的对象并将其推送到i18Notifications服务。
i18nNotifications.pushForCurrentRoute('error.fatal', 'error', {}, {
exception:exception,
cause:cause
});
为了让一个简短的故事无聊,你会看到服务拦截。正在拦截现有服务以扩展该服务,使其行为与开箱即用一样,并添加新行为以将异常推送到i18Notifications服务。
有关装饰/服务拦截的更多信息:http://csharperimage.jeremylikness.com/2014/01/interception-using-decorator-and-lazy.html
有关$ exceptionHandler的更多信息: http://docs.angularjs.org/api/ng.%24exceptionHandler