Je crée un service de journalisation pour étendre le service $ log de angular en enregistrant les erreurs (ou le débogage, le cas échéant) dans une base de données indexedDB. Voici le code:
angular.module('appLogger', ['appDatabase'])
.service('LogServices', function($log, Database) {
// ...
this.log = function(type, message, details) {
var log = {};
log.type = type
log.context = this.context;
log.message = message;
log.dateTime = moment().format('YYYY-MM-DD HH:mm:ss');
log.details = details || '';
$log[type.toLowerCase()](log);
if (type === 'ERROR' || this.logDebug) {
Database.logSave(log);
}
};
// ...
})
Cela fonctionne dans mes services comme prévu. Maintenant, le problème est que je ne peux pas utiliser mon enregistreur dans le service de base de données, car il génère une erreur de dépendance circulaire. Je comprends le problème mais je ne sais pas comment je devrais le résoudre ... Comment devrais-je résoudre ce problème?
Merci pour ton aide :-)
La raison pour laquelleAngular se plaint d'une dépendance circulaire est que ... eh bien, il y en a une.
C'est un chemin très dangereux, mais si vous savez ce que vous faites (derniers mots célèbres), il existe une solution pour contourner ce problème:
.service('LogServices', function($log, $injector) {
// ...
var Database; // Will initialize it later
this.log = function(type, message, details) {
/* Before using Database for the first time
* we need to inject it */
if (!Database) { Database = $injector.get('Database'); }
var log = {};
log.type = type
log.context = this.context;
log.message = message;
log.dateTime = moment().format('YYYY-MM-DD HH:mm:ss');
log.details = details || '';
$log[type.toLowerCase()](log);
if (type === 'ERROR' || this.logDebug) {
Database.logSave(log);
}
};
// ...
})
Voir aussi cette courte démo.
Voir cette réponse et en particulier le blog de Misko et en particulier la question de Peter dans les commentaires, dans laquelle presque le même problème est discuté.
La réponse de Misko est (en utilisant du code Java)
class Database() implements DB;
class Logger(Database db);
class LoggingDatabase(Logger log, Database db) implements DB;
Donc, dans votre application, vous avez
.service('Database', ...) // DO NOT inject the $log or LogServices here
.service('LogServices', function($log) {...}) // DO NOT inject Database here
.service('LoggingDB', function(Database, LogServices) {...})
Utilisez LoggingDB pour chaque partie de votre application où vous souhaitez une base de données qui se connecte. (Ou est-ce un enregistreur qui utilise la base de données!)
Une autre pensée
Comment se fait-il que vous ayez une base de données sur le navigateur? Est-ce que Database est un wrapper pour $ http ou $ resource ou quelque chose comme ça? Si tel est le cas, je suis d’accord avec ExpertSystem dans son option 2): n’utilisez pas $ http pour les erreurs de journalisation, car si l’erreur tue $ http? Utilisez XMLHTTPRequest à la place. Voir ici pour une discussion.
J'ai fait face à ce problème en essayant de remplacer exceptionHandler
voici le code où le problème est apparu
angular
.factory('$exceptionHandler', ExceptionHandler);
function exceptionHandler($log, sweetAlert) {// here is the problem with injecting sweetAlert
return function myExceptionHandler(exception, cause) {
//logErrorsToBackend(exception, cause);
sweetAlert.swal('Opps...', 'An error has occurred');
$log.warn(exception, cause);
};
}
et pour y remédier j'ai utilisé injector
angular
.factory('$exceptionHandler', ExceptionHandler);
ExceptionHandler.$inject = ['$injector']; //better for minification
function ExceptionHandler($injector) {
var $log, sweetAlert, $translate;// use variables for caching
return function exceptionHandler(exception, cause) {
// Add DI here to prevent circular dependency
$log = $log || $injector.get('$log');
sweetAlert = sweetAlert || $injector.get('sweetAlert');
$translate = $translate || $injector.get('$translate');
//............
}
voici un lien pour plus d'informations L'injection de résultats $ http dans une dépendance circulaire
espérons que cela vous aide