web-dev-qa-db-ja.com

AngularJS循環依存

エラー(または有効になっている場合はデバッグ)を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);
        }
    };

    // ...
})

これは意図したとおりに私のサービスで機能しています。問題は、循環依存エラーがスローされるため、データベースサービス内でロガーを使用できないことです。問題は理解していますが、どうすれば解決できるのかわかりません。どうすればこれを回避できますか?

助けてくれてありがとう:-)

14
ImSoNuts

Angularが循環依存について不平を言っている理由は...それが1つあるということです。
下るのは非常に危険な道ですが、あなたが何をしているか知っているなら(有名な最後の言葉)、それを回避する解決策があります:

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

    // ...
})

こちらもご覧ください短いデモ

31
gkalpak

この答え 、特に Miskoのブログ を参照してください。特に、ほとんど同じ問題が議論されているコメントのPeterの質問を参照してください。

ミスコの答えは(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を使用しないでください。代わりにXMLHTTPRequestを使用してください。議論については here を参照してください。

3
poshest

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を挿入すると循環依存が発生します

これがあなたに役立つことを願っています

0