Existe-t-il un moyen d'écrire une fonction globale auto-made mylogger que je pourrais utiliser dans un projet Angular2 TypeScript pour mes services ou composants au lieu d'une fonction console.log?
Mon résultat souhaité serait quelque chose comme ceci:
mylogger.ts
function mylogger(msg){
console.log(msg);
};
user.service.ts
import 'commons/mylogger';
export class UserService{
loadUserData(){
mylogger('About to get something');
return 'something';
};
};
Vous pouvez écrire ceci en tant que service, puis utiliser l'injection de dépendance pour rendre la classe disponible pour vos composants.
import {Injectable, provide} from 'angular2/core';
// do whatever you want for logging here, add methods for log levels etc.
@Injectable()
export class MyLogger {
public log(logMsg:string) {
console.log(logMsg);
}
}
export var LOGGING_PROVIDERS:Provider[] = [
provide(MyLogger, {useClass: MyLogger}),
];
Vous voudrez placer ceci dans l'injecteur de niveau supérieur de votre application en l'ajoutant au tableau de fournisseurs de bootstrap
.
import {LOGGING_PROVIDERS} from './mylogger';
bootstrap(App, [LOGGING_PROVIDERS])
.catch(err => console.error(err));
Un exemple très simple ici: http://plnkr.co/edit/7qnBU2HFAGgGxkULuZCz?p=preview
L'exemple donné par la réponse acceptée imprimera les journaux à partir de la classe de consignation, MyLogger
, au lieu de la classe en cours de journalisation.
J'ai modifié l'exemple fourni pour que les journaux soient imprimés à partir de la ligne exacte qui appelle MyLogger.log()
, par exemple:
get debug() {
return console.debug.bind(console);
}
get log() {
return console.log.bind(console);
}
J'ai trouvé comment faire ici: https://github.com/angular/angular/issues/5458
Plunker: http://plnkr.co/edit/0ldN08?p=preview
Selon les docs dans developers.mozilla,
The bind() method creates a new function that, when called, has its
this keyword set to the provided value, with a given sequence of
arguments preceding any provided when the new function is called.
Plus d'informations sur bind
ici:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
Si vous voulez utiliser la fonction 'console.log' uniquement dans votre composant, vous pouvez le faire:
import { Component, OnInit } from '@angular/core';
var output = console.log;
@Component({
selector: 'app-component',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
constructor() { }
ngOnInit() { }
printFunction(term: string): void {
output('foo');
}
}
Pourquoi ne pas utiliser la console sur votre service principal? Nous pouvons donc personnaliser et appliquer console.log
de manière conditionnelle:
myComponent.ts
export class myComponent implements OnInit {
constructor(
private config: GlobalService
) {}
ngOnInit() {
this.config.log('func name',{a:'aval'},'three');
}
}
global.service.ts
@Injectable()
export class GlobalService {
constructor() { }
this.prod = true;
public log(one: any, two?: any, three?: any, four?: any) {
if (!this.prod) {
console.log('%c'+one, 'background:red;color:#fff', two, three, four);
}
}
}
(Remarque: le premier paramètre doit être chaîne dans cet exemple);
Pour basculer console.log ON\OFF:
logger.service.ts:
import { Injectable } from '@angular/core';
@Injectable()
export class LoggerService {
private oldConsoleLog = null;
enableLogger(){
if (this.oldConsoleLog == null) { return; }
window['console']['log'] = this.oldConsoleLog;
}
disableLogger() {
this.oldConsoleLog = console.log;
window['console']['log'] = function () { };
};
}
app.component.ts:
@Component({
selector: 'my-app',
template: `your templ;ate`
})
export class AppComponent {
constructor(private loggerService: LoggerService) {
var IS_PRODUCTION = true;
if ( IS_PRODUCTION ) {
console.log("LOGGER IS DISABBLED!!!");
loggerService.disableLogger();
}
}
}
J'ai créé un enregistreur basé sur les informations fournies ici
Son très basique (hacky :-)) pour le moment, mais il conserve le numéro de ligne
@Injectable()
export class LoggerProvider {
constructor() {
//inject what ever you want here
}
public getLogger(name: string) {
return {
get log() {
//Transform the arguments
//Color output as an example
let msg = '%c[' + name + ']';
for (let i = 0; i < arguments.length; i++) {
msg += arguments[i]
}
return console.log.bind(console, msg, 'color:blue');
}
}
}
}
J'espère que cela t'aides
type safer (ish) version avec Angular 4, TypeScript 2.3
import { InjectionToken } from '@angular/core';
export type LoggerService = Pick<typeof console,
'debug' | 'error' | 'info' | 'log' | 'trace' | 'warn'>;
export const LOGGER_SERVICE = new InjectionToken('LOGGER_SERVICE');
export const ConsoleLoggerServiceProvider = { provide: LOGGER_SERVICE, useValue: console };
// ...
@NgModule({
providers: [
ConsoleLoggerServiceProvider,
//...
],
// ...
// ...
@Injectable()
export class MyService {
constructor(@Inject(LOGGER_SERVICE) log: LoggerService) {
//...
Il existe maintenant un composant de journalisation angular2 sur NPM qui prend en charge les niveaux de journalisation . https://www.npmjs.com/package/angular2-logger