![](/img/trans.png)
[英]How to decorate current state resolve function in UI-Router? Current function isn't invoked
[英]Cannot decorate AngularJS' ExceptionHandler using TypeScript, as a function isn't recognized as such
背景:
在我正在开发的项目中,我们已经从使用带有JavaScript的AngularJS(1.6.2)切换到TypeScript 2.1.5。
我们有一个应用于$exceptionHandler
服务的装饰器,它导致JavaScript异常调用向开发团队发送电子邮件的公共API; 通过这种方式,我们可以很容易地看到最终用户在野外遇到的前端错误。
问题:
我最近将这个装饰器从JavaScript转换为TypeScript。 当我尝试运行应用程序时,我遇到了什么都没有的白屏。 经过大量调试后,我发现问题是因为AngularJS希望$provide.decorator
传递一个函数以及一个依赖列表。 但是,正在观察一个对象,从而迫使Angular进行故障安全。
我通过在angular.js
设置断点来诊断问题; 由于抛出的,未处理的JavaScript异常,它特别会在第4809行(在函数createInternalInjector(cache, factory)
)失败,但是实际负责失败的部分是4854行,在函数invoke(fn, self, locals, serviceName)
内部invoke(fn, self, locals, serviceName)
。 它失败的原因是因为传递的依赖关系是['$delegate', '$injector',]
; 该集合中缺少该功能。
最后,我考虑过的一件事就是在类代码中定义一个JavaScript函数。 由于两个原因,这在我的案例中不起作用。 首先,在我们的ts.config
,我们将noImplicitAny
设置为true; 函数隐含在any
类型中。 此外,TypeScript本身似乎不会将function
识别为关键字,而是尝试将其编译为类ExceptionHandler
上的符号。
TypeScript异常处理程序:
export class ExceptionHandler {
public constructor(
$provide: ng.auto.IProviderService
) {
$provide.decorator('$exceptionHandler`, [
'$delegate',
'$injector',
this.dispatchErrorEmail
]);
}
public dispatchErrorEmail(
$delegate: ng.IExceptionHandlerService,
$injector: ng.auto.IInjectorService
): (exception: any, cause: any) => void {
return (exception: any, cause: any) => {
// First, execute the default implementation.
$delegate(exception, cause);
// Get our Web Data Service, an $http wrapper, injected...
let webDataSvc: WebDataSvc = $injector.get<WebDataSvc>('webDataSvc');
// Tell the server to dispatch an email to the dev team.
let args: Object = {
'exception': exception
};
webDataSvc.get('/api/common/errorNotification', args);
};
}
}
angular.module('app').config(['$provide', ExceptionHandler]);
原JS:
(function () {
'use strict';
angular.module('app').config(['$provide', decorateExceptionHandler]);
function decorateExceptionHandler($provide) {
$provide.decorator('$exceptionHandler', ['$delegate', '$injector', dispatchErrorEmail]);
}
function dispatchErrorEmail($delegate, $injector) {
return function (exception, cause) {
// Execute default implementation.
$delegate(exception, cause);
var webDataSvc = $injector.get('webDataSvc');
var args = {
'exception': exception,
};
webDataSvc.get('/api/common/ErrorNotification', args);
};
}
})();
问题:
1.我可以用什么方式重写TypeScript异常处理程序,以便AngularJS正确选择?
2.如果我不能,这是一个需要升级的AngularJS错误吗? 我知道事实上我不是唯一一个使用TypeScript的AngularJS的人; 由于语言选择而无法装饰服务似乎是一个非常重要的问题。
将所有内容转换为类不是TS的目的,这里的类没有用处。 JS代码应该使用类型进行扩充,并且可能使用$inject
注释进行增强。
angular.module('app').config(decorateExceptionHandler);
decorateExceptionHandler.$inject = ['$provide'];
export function decorateExceptionHandler($provide: ng.auto.IProviderService) {
$provide.decorator('$exceptionHandler', dispatchErrorEmail);
}
dispatchErrorEmail.$inject = ['$delegate', '$injector'];
export function dispatchErrorEmail(
$delegate: ng.IExceptionHandlerService,
$injector: ng.auto.IInjectorService
): (exception: any, cause: any) => void { ... }
config
需要常规函数,而不是构造函数。 原始TS代码失败的原因是没有使用new
调用ExceptionHandler
,因此this
不是对象,而this.dispatchErrorEmail
不是函数。
这是使用TypeScript命名空间执行此操作的另一种方法。 对我来说感觉有点干净,保持异常扩展功能是孤立的,并且在概念上来自C#之类的东西。
exception.module.ts
import * as angular from 'angular';
import { LoggerModule } from '../logging/logger.module';
import { ExceptionExtension } from './exception.handler';
export const ExceptionModule = angular.module('app.common.exception', [LoggerModule])
.config(ExceptionExtension.Configure)
.name;
exception.handler.ts
import { ILoggerService } from '../logging/logger.service';
export namespace ExceptionExtension {
export const ExtendExceptionHandler = ($delegate: ng.IExceptionHandlerService, logger: ILoggerService) => {
return function (exception: Error, cause?: string): void {
$delegate(exception, cause);
logger.error(exception.message, "Uncaught Exception", cause ? cause : "");
}
};
ExtendExceptionHandler.$inject = ['$delegate', 'ILoggerService'];
export const Configure = ($provide: ng.auto.IProvideService) => {
$provide.decorator('$exceptionHandler', ExtendExceptionHandler);
};
Configure.$inject = ['$provide'];
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.