如何检查是否已定义angularjs控制器

Sir*_*ert 9 config controllers angularjs

我有这样定义的app:

angular.module("myApp", [...])
  .config(function ($stateProvider, $controllerProvider) {
    if (isControllerDefined(controllerName)) {
      do_stuff();
    }
  })
Run Code Online (Sandbox Code Playgroud)

控制器以这种方式定义:

angular.module("myApp")
  .controller("myController", function ($scope) { ... });
Run Code Online (Sandbox Code Playgroud)

isControllerDefined()如果我有控制器的名称,我如何定义(在上面的配置中)检查给定的控制器是否存在?我觉得我应该做一些像这样的事情:

var ctrl = angular.module("myApp").getController("myController");
var ctrl = $controllerProvider.get("myController");
Run Code Online (Sandbox Code Playgroud)

或类似的东西...但我找不到任何功能.救命?

fra*_*acz 9

可以检查控制器是否存在的服务示例.请注意,它会查找具有指定名称的全局函数以及$controller提供程序中的控制器.

angular.service('ControllerChecker', ['$controller', function($controller) {
  return {
    exists: function(controllerName) {
      if(typeof window[controllerName] == 'function') {
        return true;
      }
      try {
        $controller(controllerName);
        return true;
      } catch (error) {
        return !(error instanceof TypeError);
      }
    }
  };
}]);
Run Code Online (Sandbox Code Playgroud)

小提琴的用法.


Jas*_*rke 6

前几天我遇到了同样的问题.我在当前接受的答案中遇到了一些问题,即因为我的一个控制器在实例化时正在执行初始化调用以填充一些数据(即):

function ExampleController($scope, ExampleService) {
    ExampleService.getData().then(function(data) {
        $scope.foo = data.foo;
        $scope.bar = data.bar
    });
}
Run Code Online (Sandbox Code Playgroud)

目前,当前接受的答案实际上将在丢弃控制器之前实例化控制器.这导致在每个请求上进行多次API调用(一个用于验证控制器是否存在,一个用于实际使用控制器).

我在$controller 源代码中进行了一些挖掘 ,发现你可以传入一个未记录的参数,later这将延迟实例化.但是,它仍然会运行所有检查以确保控制器存在,这是完美的!

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;
            }
        }
    };
}]);
Run Code Online (Sandbox Code Playgroud)

更新:作为装饰者可能更容易:

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;
    }]);
}]);
Run Code Online (Sandbox Code Playgroud)

然后你可以简单地注入$controller和调用exists(...)

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