Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get a hold of an object (function of controller, service or directive) from another module

Is it possible to access functions that sit either in the same module or in a different one?

Something like:

var fooDir = angular.module("directives").get("foo")

… or:

var myCtrl = angular.module("app").controllers["myCtrl"]

I guess for services we can use an injector:

inj = angular.injector(['myServicesModule'])
$myService = inj.get('$myService')

… but will it work for controllers and directives?

like image 806
iLemming Avatar asked Mar 17 '14 18:03

iLemming


1 Answers

Get the injector

Injector from modules

For example, to get the injector of an empty and not attached to DOM application instance, assuming you have your own module test:

angular.injector(['ng', 'test']);

Injector from existing app

For example, to get the injector of the application managing a selected node with id test:

angular.element(document.getElementById('test')).injector();

Get an instance from the injector

Assuming you get the injector as the injector variable


Get a service instance

To get the $rootScope instance:

injector.get('$rootScope');

Get a controller instance

Assuming you get a controller named TestCtrl:

injector.get('$controller')('TestCtrl', { $scope: {} });

Get an element with a directive compiled

Assuming you have a directive test, to get the compiled element against $rootScope:

injector.get('$compile')('<div a/>')(injector.get('$rootScope'));

Helpers from angular jqLite or jQuery

Besides injector to get the injector of a jqLite or jQuery collection, you can, assuming a jqLite or jQuery collection wrapping an attached DOM element which exists in your application, as variable $element:


Get the controller instance attached to DOM element

$element.controller();

Get the scope instance attached to DOM element

$element.scope();

Get the isolate scope instance attached to DOM element

$element.isolateScope();

Get the hidden data attached by angular to DOM element

$element.inheritedData();

Moreover, each time what you get is an instance of a JavaScript constructor (services, controllers), you can get this constructor using the constructor property of the instance.


List of registered services, controllers, etc.

There is no exposed list of registered services, controllers, etc. You can, however, override providers methods, to get, for example, the registrations occuring on top of module 'ng':

angular.module('ng').config(
    function ($provide, $compileProvider, $controllerProvider) {
      
        angular.forEach(['service', 'provider', 'controller'], function (m) {
            var _m = $provide[m];
            $provide[m] = function () {
                console.log('$provide', m, arguments);
                return _m.apply($provide, arguments);
            };
        });

        angular.forEach(['directive'], function (m) {
            var _m = $compileProvider[m];
            $compileProvider[m] = function () {
                console.log('$compileProvider', m, arguments);
                return _m.apply($compileProvider, arguments);
            };
        });
      
        angular.forEach(['register'], function (m) {
            var _m = $controllerProvider[m];
            $controllerProvider[m] = function () {
                console.log('$controllerProvider', m, arguments);
                return _m.apply($controllerProvider, arguments);
            };
        });
      
    });

This way you can get your own lists. But it's called overriding the framework and you should not do that.

like image 183
lib3d Avatar answered Nov 15 '22 09:11

lib3d