2016-10-03 27 views
0

我嘗試使用ng-notifications-bar模塊時通知依賴性發現,我有這樣的代碼:角 - 使用ngNotificationsBar

angular.module('app', [ 
    uiRouter, 
    Common.name, 
    Components.name, 
    angularMaterial, 
    'ngTable', 
    'gridster', 
    'ngNotificationsBar' 
    ]) 
    .factory('$exceptionHandler', ['notifications', function(notifications) { 
    return function(exception, cause) { 
     notifications.showError({message: exception}); 
    }; 
    }]); 

,但得到的錯誤:

[$injector:cdep] Circular dependency found: $rootScope <- notifications <- $exceptionHandler <- $rootScope <- $timeout <- $$rAF <- $mdGesture

我試圖修改庫使用$injector得到$超時和$ rootScope但這並沒有幫助還試圖用$injector得到notifications$exceptionHandler工廠,但得到了同樣的錯誤。

+0

什麼是你的'$ injector'嘗試樣子? –

+0

@MattWay'變量$ rootScope = $ injector.get( '$ rootScope');'或'VAR通知= $ injector.get( '通知');' – jcubic

+0

你叫'得到()'內部或外部返回功能? –

回答

2

很糟糕的設計從角度看它在這一個。由於依賴關係,您無法將$rootScope以任何形式注入$exceptionHandler

您可以使用$injector來解決這些類型的(你手中的)依賴問題,你只需要確保在返回函數內部使用注入模塊來確保在調用時.get()從屬模塊已實際加載。例如:

// won't not be available here 
var rootScope = $injector.get('$rootScope'); 

return function(exception, cause) { 
    // will be available here 
    var rootScope = $injector.get('$rootScope'); 
}; 

這是因爲$injector用來搶在運行時的依賴。

+1

我用'VAR通知= $ injector.get(「通知」);'在功能insidead所以我並不需要修改其中'使用$ rootScope'庫。 – jcubic

1

有一個很好的清潔面向對象的設計,以避免循環依賴:使用dependency inversion principle。創建一個通用的服務,您可以將處理程序,並從run塊設置。基本上所有其他解決方案都提供了類似的東西,但是在角度外使用全局變量,或繞過自動依賴注入。

angular.module("App", []) 
 
.factory("notifications", function($rootScope) { 
 
    $rootScope.notifications = []; 
 
    function showMessage(msg) { 
 
    $rootScope.notifications.push(msg); 
 
    } 
 
    return { showMessage }; 
 
}) 
 
.factory("$exceptionHandler", function(MyExceptionService) { 
 
    return function(e, cause) { 
 
    MyExceptionService.fire(e, cause); 
 
    }; 
 
}) 
 
.factory("MyExceptionService", function() { 
 
    const handlers = []; 
 
    return { 
 
    addHandler(h) { handlers.push(h); }, 
 
    fire(e, cause) { handlers.forEach(h => { h(e, cause); }) } 
 
    }; 
 
}) 
 
.controller("MyCtrl", function($scope) { 
 
    $scope.clicked =() => { 
 
    throw new Error("Error made"); 
 
    }; 
 
}) 
 
.run(function(MyExceptionService, notifications) { 
 
    MyExceptionService.addHandler(err => { 
 
    notifications.showMessage({ message: err.message }); 
 
    }); 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script> 
 
<div ng-app="App" ng-controller="MyCtrl"> 
 
    <button ng-click="clicked()">Make Error</button> 
 
    <div>Errors:</div> 
 
    <div ng-repeat="item in notifications">{{item}}</div> 
 
</div>

爲了便於比較,這裏是錯誤的(與循環依賴):

angular.module("App", []) 
 
.factory("notifications", function($rootScope) { 
 
    $rootScope.notifications = []; 
 
    function showMessage(msg) { 
 
    $rootScope.notifications.push(msg); 
 
    } 
 
    return { showMessage }; 
 
}) 
 
.factory("$exceptionHandler", function(notifications) { 
 
    return function(e, cause) { 
 
    notifications.showMessage({ message: err.message }); 
 
    }; 
 
}) 
 
.controller("MyCtrl", function($scope) { 
 
    $scope.clicked =() => { 
 
    throw new Error("Error made"); 
 
    }; 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script> 
 
<div ng-app="App" ng-controller="MyCtrl"> 
 
    <button ng-click="clicked()">Make Error</button> 
 
    <div>Errors:</div> 
 
    <div ng-repeat="item in notifications">{{item}}</div> 
 
</div>