AngularJS循环依赖

时间:2014-04-07 09:30:21

标签: angularjs circular-dependency

我正在创建一个记录器服务,通过将错误(或调试,如果启用)保存到indexedDB数据库中来扩展angular的$ log服务。这是代码:

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);
        }
    };

    // ...
})

这在我的服务中按预期工作。现在的问题是我无法在数据库服务中使用我的记录器,因为它会抛出循环依赖性错误。我理解这个问题,但我不知道如何解决它......我该如何解决这个问题?

感谢您的帮助: - )

3 个答案:

答案 0 :(得分:29)

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);
        }
    };

    // ...
})

另请参阅此 short demo

答案 1 :(得分:3)

请参阅this answer,特别是Misko's 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或其他东西的包装器吗?如果是这种情况,我同意他的2)选项中的ExpertSystem:不要使用$ http来记录错误,因为如果错误导致$ http怎么办?请改用XMLHTTPRequest。有关讨论,请参阅here

答案 2 :(得分:0)

我在尝试覆盖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');
        //............
    }

这是一个更多信息Injecting $http results in a Circular dependency

的链接

希望这可以帮助你