Круговая зависимость AngularJS
Я делаю службу регистрации, чтобы расширить службу журнала angular $, путем сохранения ошибок (или отладки, если они включены) в базу данных indexedDB. Здесь код:
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);
}
};
// ...
})
Это работает в моих службах по назначению. Теперь проблема в том, что я не могу использовать свой регистратор внутри службы базы данных, потому что он выдает ошибку циклической зависимости. Я понимаю проблему, но я не знаю, как ее разрешить... Как мне обойти это?
Спасибо за помощь: -)
Ответы
Ответ 1
Причина Angular заключается в том, что жалоба на круговую зависимость заключается в том, что... ну есть один.
Это очень опасный путь, чтобы пойти вниз, но если вы знаете, что делаете (знаменитые последние слова), тогда есть решение обходить это:
.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);
}
};
// ...
})
См. также эту короткую демонстрацию.
Ответ 2
См. этот ответ и, в частности, Misko blog и, в частности, вопрос Питера в комментариях, в которых обсуждается почти одна и та же проблема.
Ответ Misko (с использованием кода Java)
class Database() implements DB;
class Logger(Database db);
class LoggingDatabase(Logger log, Database db) implements DB;
Итак, в вашем приложении у вас есть
.service('Database', ...) // DO NOT inject the $log or LogServices here
.service('LogServices', function($log) {...}) // DO NOT inject Database here
.service('LoggingDB', function(Database, LogServices) {...})
Используйте LoggingDB для каждой части вашего приложения, где вы хотите, чтобы база данных регистрировалась. (Или это журнал, который использует базу данных!)
Другая мысль
Как у вас есть база данных в браузере? Является ли база данных оболочкой для $http или $resource или чего-то еще? Если это так, я согласен с ExpertSystem в его варианте 2): не используйте $http для регистрации ошибок, потому что, если ошибка убивает $http? Вместо этого используйте XMLHTTPRequest. См. здесь для обсуждения.
Ответ 3
Я столкнулся с этой проблемой при попытке переопределить exceptionHandler
вот код, в котором появилась проблема
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);
};
}
и для его исправления я использовал 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');
//............
}
вот ссылка для дополнительной информации Ввод $http приводит к циклической зависимости
надеюсь, что это поможет вам