我可以访问$ controllerProvider,但无法通过以下方法访问$ controller
angular.module(MODULE_NAME, ['common'])
.config(['$routeProvider','$controllerProvider',
function($routeProvider, $controllerProvider) {
console.log($controllerProvider);//defined
console.log($controller);//undefined
}]);
如果我使用$ controller作为依赖注入,它就是
Unknown provider: $controller
但我需要访问它,我该怎么做
修改
我需要这个,因为我想检查我的控制器是否存在。以下是post我使用此代码的地方
try {
$controller(controllerName);
listControlerName = MODULE_NAME+'ListController';
} catch (error) {
listControlerName = 'CommonListController';
}
CONTEXT
我正在创建项目的架构。我的项目结构如下。
现在我的计划是需要开发一个新模块(MODX),然后如果有一些额外的功能,那么只有开发人员将通过继承公共ListController为该模块创建一个新的MODXListController。否则他们不需要创造任何东西。
因此系统将检查该模块是否包含MODXListController。如果没有,那么系统将使用Common ListController。
我不想创建一个继承常见ListController但不做任何额外更改的MODXListController。因为我有大约25个模块,所有这些模块大部分都是共享相同的功能。
答案 0 :(得分:1)
没有显式继承所有控制器(这是可接受的但是详细的解决方案),一个很好的选择是将控制器切换功能包装到mod-controller
指令(类似于ng-controller
),类似于:
angular.module('common', [])
.constant('MODULE_NAME', 'Common')
.constant('modControllers', [])
.controller('CommonEditController', ...);
.controller('CommonListController', ...);
.directive('modController', function (MODULE_NAME, modControllers) {
return {
restrict: 'A',
scope: true,
priority: 500,
controller: function ($controller, $attrs, $scope) {
var ctrlName = (modControllers.indexOf($attrs.modController) >=0 ? MODULE_NAME : 'Common') + $attrs.modController;
angular.extend(this, $controller(ctrlName, { $scope: $scope }));
});
};
});
angular.module('mod1', ['common'])
.constant('MODULE_NAME', 'Mod1')
.constant('modControllers', ['ListController']);
.controller('Mod1ListController', function ($controller) {
angular.extend(this, $controller('CommonListController');
...
});
当应在应用程序代码而不是视图(即路由和指令控制器)中指定控制器时,可以使用控制器工厂完成类似的操作。
angular.module('common')
.provider('ctrlFactory', function (MODULE_NAME, modControllers) {
function factoryFn(ctrlName) {
return (modControllers.indexOf(ctrlName) >=0 ? MODULE_NAME : 'Common') + ctrlName;
};
this.get = this.$get = factoryFn;
});
它可以注入指令并用作
...
controller: ctrlFactory('ListController')
由于它返回控制器名称而不是$controller
实例并且仅依赖于常量服务(MODULE_NAME,modControllers),因此服务提供者也可以像服务实例一样使用来声明路由控制器config
阻止:
...
controller: ctrlFactoryProvider.get('ListController')
因为$controller
没有公开已注册的控制器列表,所以尝试捕获它作为自动解决方案,这是人们可能想要做的最后一件事:除了它是一个黑客,它只是抑制可能的例外并损害可测试性。
答案 1 :(得分:0)
在.config中,您只能使用提供程序(例如$ routeProvider)。
在.run中,您只能使用服务实例(例如$ route)。
$ controller属于service类型,无法在.config中使用。
有关此阅读here.
的详细信息在this线程上有关Stack Overflow的详细讨论显示了可以注入其他内容的内容。
答案 2 :(得分:0)
您无法将$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);
}
}
};
}]);
现在您可以注入ControllerChecker
并调用其exists(CtrlName)
函数来检查您的控制器是否已定义。