javascript - Importing multiple AngularJS module's factories -
i wondering if there way import factories i've defined in angularjs module controller without having list them all. have file named foo.js
containing:
angular.module("foo", []) .factory("bar1", function() {...}) .factory("bar2", function() {...}) .factory("bar3", function() {...}) .factory("bar4", function() {...});
now, in controller.js
file have:
angular.module("myapp.controllers", ["foo"]). controller("mainctrl", ["bar1", "bar2", "bar3", "bar4", function(bar1, bar2, bar3, bar4) { //do stuff various bars }]);
i wondering if there's elegant way controller, since imports module foo
, see factories (or providers, or services, or directives matter of fact).
yes, possible.
you can dynamically load module examine _invokequeue
field (see https://stackoverflow.com/a/19412176/646543) in order retrieve names of factories/controllers/etc defined in module.
you can use $injector
service retrieve factories.
to demonstrate, i've created quick proof-of-demo. should able directly copy-and-paste introspectmodule
factory app functionality.
// creating test services angular.module('test-services', []) .factory('bar1', function() { return { 'stuff': function() { return 'calling bar1' } }; }) .factory('bar2', function() { return { 'stuff': function() { return 'calling bar2' } }; }); angular.module('myapp', ['test-services']) .factory('introspectmodule', function($injector) { // factory dynamically return services/controllers/directives/etc // given module name. return function (modulename) { var out = {}; angular.module(modulename)._invokequeue.foreach(function(item) { var name = item[2][0]; out[name] = $injector.get(name); }); return out; }; }) .controller('mainctrl', function($scope, introspectmodule) { // , i'm using var testservices = introspectmodule('test-services'); $scope.test = testservices.bar1.stuff(); });
here's working plnkr of above.
alternatively, if feels hacky, try creating 'composite' factory:
angular.module("test-services", []) .factory("bar1", function() {...}) .factory("bar2", function() {...}) .factory("bar3", function() {...}) .factory("bar4", function() {...}) .factory("everybar", ["bar1", "bar2", "bar3", "bar4", function(bar1, bar2, bar3, bar4) { return { 'bar1': bar1, 'bar2': bar2, 'bar3': bar3, 'bar4': bar4 }; }]);
then, inside controllers, do:
angular.module("myapp.controllers", ["test-services"]). controller("mainctrl", ["everybar", function(everybar) { everybar.bar1.stuff(); }]);
obviously, disadvantage of approach results in deal of redundancy when setting services -- we're still manually listing everything.
however, if need use same services multiple times in several different controllers, creating composite service @ least allow avoid having list bunch of parameters in every controller.
it's more explicit first solution, , allows cleanly enumerate services want rather mucking around in internals of angular, , lets extend services, add helper/wrapper functions, etc.
Comments
Post a Comment