gpt4 book ai didi

angular - 获取 Angular 2 和 TypeScript 中当前正在执行的函数的名称

转载 作者:搜寻专家 更新时间:2023-10-30 21:50:30 24 4
gpt4 key购买 nike

这个问题针对的是使用 TypeScript 的 Angular 2 应用程序。

我需要记录一条自定义消息、类或组件的名称以及我正在记录的函数的名称。

现在,我正在对这些值进行硬编码(同样这是 TypeScript):

class MyService {
getUsers() {
console.log('MyService.getUsers()', 'I am here');
}

但是,我不想硬编码类名和函数名。

我设法得到类或组件的名称:

console.log(MyService.name);

但是我怎样才能得到当前正在执行的函数的名称呢?

最佳答案

这个答案需要 Lodash 的一些基本功能。您应该能够用对应的 JavaScript 代码替换该代码。

日志服务.ts

import {FactoryProvider, Injectable, InjectionToken, Optional} from '@angular/core';
import * as _ from 'lodash';

const PREFIX_SEPARATOR = ':';

@Injectable()
export class LogService {
/**
* Global logger
*/
public static log: LogService = new LogService();

/**
* Creates an injectable logger that can be used by a module.
*/
public static provide(token: InjectionToken<LogService>): FactoryProvider {
return {
provide: token,
useFactory: (log: LogService) => {
let prefix = token.toString().replace(/^InjectionToken\s/, '').replace(/Logger$/, '').toUpperCase();
return log.prefix(prefix);
},
deps: [LogService]
};
}

/**
* Gets the stack trace when browser adds stack property.
*/
private static getStackTrace(): string[] | undefined {
try {
let ex = new Error() as Object;
if (ex.hasOwnProperty('stack') && _.isString(ex['stack'])) {
return ex['stack'].split('\n');
}
} catch (err) {
// do nothing
}
return void 0;
}

/**
* Gets the constructor name from the call stack, but only on Chrome browsers.
*/
private static getConstructorName(depth: number): string | undefined {
if (_.isUndefined(window['chrome'])) {
return void 0;
}
let trace = LogService.getStackTrace();
if (!trace || trace.length <= depth) {
return void 0;
}
let str = trace[depth];
if (!/\s+at\snew\s/.test(str)) {
return void 0;
}
let match = /new ([$A-Z_][0-9A-Z_$]*)/i.exec(str);
if (!match || match.length < 2) {
return void 0;
}
return match[1].replace(/(Component|Directive|Service|Factory|Pipe|Resource|Module|Resolver|Provider)$/, '');
}

/**
* Output prefix
*/
private prefixName: string;

/**
* Flag if debugging is enabled.
*/
private _debug: boolean = process.env.ENV && process.env.ENV === 'development';

/**
* Allows for optional prefix.
*/
public constructor(@Optional() prefix?: string) {
this.prefixName = prefix;
}

/**
* Creates a logger with an automatic prefix.
*/
public withPrefix(): LogService {
if (!this._debug) {
return this;
}
return this.prefix(LogService.getConstructorName(4));
}

/**
* Creates a new logger with the given prefix in all output messages.
*/
public prefix(prefix?: string): LogService {
return prefix
? new LogService((this.prefixName || '') + prefix + PREFIX_SEPARATOR)
: this;
}

public get info(): Function {
if (!console || !console.info) {
return _.noop;
}
return this.prefixName
? console.info.bind(console, this.prefixName)
: console.info.bind(console);
}

public get debug(): Function {
if (!this._debug || !console || !console.log) {
return _.noop;
}
return this.prefixName
? console.log.bind(console, this.prefixName)
: console.log.bind(console);
}

public get warn(): Function {
if (!console || !console.warn) {
return _.noop;
}
return this.prefixName
? console.warn.bind(console, this.prefixName)
: console.warn.bind(console);
}

public get error(): Function {
if (!console || !console.error) {
return _.noop;
}
return this.prefixName
? console.error.bind(console, this.prefixName)
: console.error.bind(console);
}
}

日志服务.module.ts

您必须在您的 ngModule 中将此服务作为单例导出,然后在您的主模块中调用 forRoot()。在您的其他模块中,您可以正常导入该模块。

@NgModule({
})
export class LogModule {
public static forRoot() {
return {
ngModule: LogModule,
providers: [
LogService
]
};
}
}

为每个模块创建记录器

您可以通过为该模块创建可注入(inject) token 来创建为每个模块名称添加前缀的记录器。

此示例用于 UI 模块。

export const UI_LOGGER = new InjectionToken<LogService>('UILogger');

@NgModule({
providers: [
LogService.provide(UI_LOGGER)
]
})
export class UIModule {
}

您不能将这个新的记录器注入(inject)到您的 UI 组件中。

@Component({})
export class MyComponent {
private log: LogService; // logger with constructor name

public constructor(@Inject(UI_LOGGER) log: LogService) {
this.log = log.withPrefix();
}
}

调用 log.withPrefix() 使用构造函数名称创建一个新记录器,并且还具有模块名称。

关于angular - 获取 Angular 2 和 TypeScript 中当前正在执行的函数的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45439677/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com