How to check if an angularjs controller has been defined

后端 未结 5 1620
被撕碎了的回忆
被撕碎了的回忆 2021-01-17 20:35

I\'ve got an app defined this way:

angular.module(\"myApp\", [...])
  .config(function ($stateProvider, $controllerProvider) {
    if (isControllerDefined(co         


        
5条回答
  •  旧巷少年郎
    2021-01-17 21:13

    I came across this exact same issue the other day. I had a few issues with the currently accepted answer, namely because one of my controllers was performing an initialization call out to the server upon instantiation to populate some data (i.e):

    function ExampleController($scope, ExampleService) {
        ExampleService.getData().then(function(data) {
            $scope.foo = data.foo;
            $scope.bar = data.bar
        });
    }
    

    As it stands, the currently accepted answer will actually instantiate the controller, before discarding it. This lead to multiple API calls being made on each request (one to verify that the controller exists, one to actually use the controller).

    I had a bit of a dig around in the $controller source code and found that there's an undocumented parameter you can pass in called later which will delay instantiation. It will, however, still run all of the checks to ensure that the controller exists, which is perfect!

    angular.factory("util", [ "$controller", function($controller) {
        return {
            controllerExists: function(name) {
                try {
                    // inject '$scope' as a dummy local variable
                    // and flag the $controller with 'later' to delay instantiation
                    $controller(name, { "$scope": {} }, true);
                    return true;
                }
                catch(ex) {
                    return false;
                }
            }
        };
    }]);
    

    UPDATE: Probably a lot easier as a decorator:

    angular.config(['$provide', function($provide) {
        $provide.delegate('$controller', [ '$delegate', function($delegate) {
            $delegate.exists = function(controllerName) {
                try {
                    // inject '$scope' as a dummy local variable
                    // and flag the $controller with 'later' to delay instantiation
                    $delegate(controllerName, { '$scope': {} }, true);
                    return true;
                }
                catch(ex) {
                    return false;
                }
            };
    
            return $delegate;
        }]);
    }]);
    

    Then you can simply inject $controller and call exists(...)

    function($controller) {
        console.log($controller.exists('TestController') ? 'Exists' : 'Does not exist');
    }
    

提交回复
热议问题