The current organization of the AngularJS module requires circular links to the module

I have a SPA that uses ngTable and ui-bootstrap. The page links to the top-level controller defined in the top-level module and several nested controllers that are defined in other modules. There are some clear references from nested controllers to services or scope variables in the top-level controller, so nested modules have links to the top-level module. However, in order for this to run without error, I have to reference all nested modules from the top-level module.

If I do not reference nested modules from the top level module, I get an error like this:

Error: [ng:areq] Argument 'DataSourcesCtrl' is not a function, got undefined
http://errors.angularjs.org/1.2.4/ng/areq?p0=DataSourcesCtrl&p1=not%20a%20function%2C%20got%20undefined
minErr/<@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:78
assertArg@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:1358
assertArgFn@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:1369
@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:6682
applyDirectivesToNode/nodeLinkFn/<@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:6098
forEach@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:307
nodeLinkFn@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:6085
compositeLinkFn@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:5551
publicLinkFn@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:5459
.link@http://run.plnkr.co/plunks/EBVfG1gWYv7xf8sa5v8a/ui-bootstrap-tpls-0.10.0.js:2822
nodeLinkFn@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:6140
compositeLinkFn@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:5548
publicLinkFn@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:5459
boundTranscludeFn@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:5570
controllersBoundTransclude@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:6160
ngRepeatAction@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:18996
$watchCollectionAction@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:11449
Scope.prototype.$digest@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:11552
Scope.prototype.$apply@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:11803
bootstrap/doBootstrap/<@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:1297
invoke@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:3644
bootstrap/doBootstrap@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:1296
bootstrap@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:1309
angularInit@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:1258
@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.js:20306
n.Callbacks/j@http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js:2
n.Callbacks/k.fireWith@http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js:2
.ready@http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js:2
K@http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js:2  

      


<div class="tab-pane ng-scope" ng-repeat="tab in tabs" ng-class="{active: tab.active}" tab-content-transclude="tab">

      

As you can see in my plunkr that demonstrates this, "DataSourcesCtrl" is the controller defined in "DataSourcesModule" in "dataSourcesMod.js". If you comment out the line at the top of "diagapp.js" it works without error.

This is what the top of "diagapp.js" looks like:

var diagapp = angular.module("DiagApp", ['ui.bootstrap'
//                 , 'DataSourcesModule' // Comment out this line to demonstrate problem
                                     ]);

      

I think now I can understand why I have to load all modules in the top level module, because otherwise there is no other way to load those modules. However, when I do this, I end up with links to circular modules, which seems to be wrong. Nothing directly inside the top-level module refers to anything in nested modules.

It seems I need to customize my modular organization. What's the best way to handle this?

0


source to share


1 answer


I think the obvious and sensible advice would be to have a top-level module that loads all the other required modules for the page, along with any configuration settings for that module, but that doesn't have anything that is directly needed for any other modules.



In this example, this would mean splitting some parts of the top-level "DiagApp" module into a "DiagMod" module. This will include any components that other modules need to use. If the top-level module does not need any configuration parameters, then the top-level module will only have one line defining all modules used in the page, including the new "DiagMod" module.

0


source







All Articles