ui-router包装器中的Angular.js循环依赖性错误

时间:2015-11-07 14:06:25

标签: javascript angularjs angular-ui-router angularjs-injector

我正在遵循John Papa的角度风格指南(https://github.com/johnpapa/angular-styleguide#routing)并在本指南中提供的角度ui-router周围使用自定义包装。但是,包装器对我不起作用,并且在注入$ state时出现循环依赖性错误:

Uncaught Error: [$injector:cdep] Circular dependency found: $rootScope <- $timeout <- $$rAF <- $$animateQueue <- $animate <- toastr <- logger <- $exceptionHandler <- $rootScope <- $state <- routerHelper

我尝试使用$ injector手动注入$ state但这会给我一个未知的提供程序错误。

以下是代码:

(function() {
'use strict';

angular
    .module('blocks.router')
    .provider('routerHelper', routerHelperProvider);

routerHelperProvider.$inject = ['$locationProvider', '$stateProvider', '$urlRouterProvider', '$injector'];

function routerHelperProvider($locationProvider, $stateProvider, $urlRouterProvider) {


    this.$get = RouterHelper;

    $locationProvider.html5Mode(true);

    RouterHelper.$inject = ['$state'];

    function RouterHelper($state) {
        var hasOtherwise = false;

        var service = {
            configureStates: configureStates,
            getStates: getStates
        };

        return service;

        function configureStates(states, otherwisePath) {
            states.forEach(function (state) {
                $stateProvider.state(state.state, state.config);
            });
            if (otherwisePath && !hasOtherwise) {
                hasOtherwise = true;
                $urlRouterProvider.otherwise(otherwisePath);
            }
        }

        function getStates() {
            return $state.get();
        }
    }

}
})(); 

1 个答案:

答案 0 :(得分:3)

我认为这是toastr而不是UI路由器代码的问题。

John Papa将他的例子基于简单的'toastr'包而不是'angular-toastr'包。

toastr:https://github.com/CodeSeven/toastr

angular-toastr:https://github.com/Foxandxss/angular-toastr

使用'toastr'包,他使用常量注册toastr的全局实例:

    .module('app.core')
    .constant('toastr', toastr);

使其可用于注入记录器服务:

logger.$inject = ['$log', 'toastr'];

/* @ngInject */
function logger($log, toastr) {

但是,如果使用angular-toastr包,那么toastr对象会在一些角度对象上引入一组依赖项:

$rootScope <- $timeout <- $$rAF <- $$animateQueue <- $animate <- toastr

这会导致循环依赖,因为$ rootScope具有使用logger / toastr对象的异常处理:

toastr <- logger <- $exceptionHandler <- $rootScope

我不确定如何正确地重构这个以消除循环依赖。因此,作为临时解决方法,我更改了记录器服务,以使用$ injector延迟解析toastr依赖项。不理想,但我能够转向其他紧迫的问题。

logger.$inject = ['$log', '$injector']; // 'toastr'

/* @ngInject */
function logger($log, $injector) { // toastr

    var service = {
        showToasts: true,

        info    : info,
        success : success,
        warning : warning,
        error   : error,

        // straight to console; bypass toastr
        log     : $log.log
    };

    return service;
    /////////////////////


    function info(message, data, title) {
        var toastr = $injector.get('toastr');

        toastr.info(message, title);
        $log.info('Info: ' + message, data);
    }

    function success(message, data, title) {
        var toastr = $injector.get('toastr');

        toastr.success(message, title);
        $log.info('Success: ' + message, data);
    }

    function warning(message, data, title) {
        var toastr = $injector.get('toastr');

        toastr.warning(message, title);
        $log.warn('Warning: ' + message, data);
    }

    function error(message, data, title) {
        var toastr = $injector.get('toastr');

        toastr.error(message, title);
        $log.error('Error: ' + message, data);
    }

}