下面的方法可以访问$controllerProvider但是不能访问$controller
angular.module(MODULE_NAME, ['common'])
.config(['$routeProvider','$controllerProvider',
function($routeProvider, $controllerProvider) {
console.log($controllerProvider);//defined
console.log($controller);//undefined
}]);
如果我使用 $controller 作为依赖注入(inject),它会提供
Unknown provider: $controller
但是我需要访问它,我该怎么做
编辑
我需要这个,因为我想检查我的 Controller 是否存在。这是我使用此代码的 post
try {
$controller(controllerName);
listControlerName = MODULE_NAME+'ListController';
} catch (error) {
listControlerName = 'CommonListController';
}
语境
我正在创建一个项目的架构。我的项目结构如下。
- 我有一个 COMMON 模块。与 ListController、EditController、ViewController
- 我还有一些其他模块,例如 MOD1、MOD2 等,带有 MOD1ListController、MOD1EditController、MOD1ViewController 等。
- 那些模块特定的 Controller 从通用模块扩展相应的 Controller 。
现在我的计划是在需要开发一个新模块(MODX)的同时,如果有一些额外的功能,那么只有开发人员通过继承公共(public)ListController为该模块创建一个新的MODXListController。否则他们不需要创建任何东西。
因此系统将检查该模块是否包含 MODXListController。如果不是,则系统将使用 Common ListController。
我不想创建一个继承通用 ListController 但不做任何额外更改的 MODXListController。因为我有很多模块,将近 25 个,而且大部分都共享相同的功能。
最佳答案
在不显式继承所有 Controller 的情况下(这是可以接受但冗长的解决方案),一个很好的替代方法是将 Controller 切换功能包装到 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');
...
});
当 Controller 应该在应用程序代码而不是 View 中指定时(即路由和指令 Controller ),类似的事情可以用 Controller 工厂完成。
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;
});
它可以被注入(inject)到指令中并用作
...
controller: ctrlFactory('ListController')
由于它返回 Controller 名称而不是 $controller
实例并且只依赖于常量服务(MODULE_NAME,modControllers),服务提供者也可以像服务实例一样使用在 config
block 中声明路由 Controller :
...
controller: ctrlFactoryProvider.get('ListController')
因为 $controller
没有公开已注册 Controller 的列表, try catch 它作为自动解决方案浮现在脑海中,这是人们可能最不想做的事情:除此之外hack,它只是抑制了可能的异常并破坏了可测试性。
关于angularjs - 未知提供者 : $controller,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33823570/