Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 未知提供程序:$controller_Angularjs - Fatal编程技术网

Angularjs 未知提供程序:$controller

Angularjs 未知提供程序:$controller,angularjs,Angularjs,我可以访问$controllerProvider,但无法使用以下方法访问$controller angular.module(MODULE_NAME, ['common']) .config(['$routeProvider','$controllerProvider', function($routeProvider, $controllerProvider) { console.log($controllerProvider);//defined

我可以访问$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
但我需要访问它,我该怎么做

编辑

我需要这个,因为我想检查我的控制器是否存在。下面是我使用此代码的位置

try {
     $controller(controllerName);
     listControlerName = MODULE_NAME+'ListController';
} catch (error) {
     listControlerName = 'CommonListController';
}
上下文

我正在创建一个项目的架构。我的项目结构如下

  • 我有一个通用模块。使用ListController、EditController、ViewController
  • 我还有一些其他模块,如MOD1、MOD2等,包括MOD1ListController、MOD1EditController、MOD1ViewController等等
  • 这些特定于模块的控制器从公共模块扩展了相应的控制器
  • 现在我的计划是,当需要开发一个新模块(MODX)时,如果有一些额外的功能,那么只有开发人员会通过继承公共ListController为该模块创建一个新的MODXListController。否则他们不需要创造任何东西

    所以系统将检查该模块是否包含MODXListController。若并没有,那个么系统将使用公共ListController


    我不想创建一个继承公共ListController但不做任何额外更改的MODXListController。因为我有很多模块,将近25个,而且大部分都共享相同的功能。

    在.config中,您只能使用提供程序(例如$routeProvider)

    在.run中,您只能使用服务实例(例如$route)

    $controller属于服务类型,无法在.config中使用

    欲了解更多有关此的详细信息,请阅读


    关于线程堆栈溢出的详细讨论显示了可以注入到其他线程中的内容。

    您不能将
    $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)
    函数来检查您的控制器是否已定义。

    而无需显式继承所有控制器(这是可接受但详细的解决方案),一个好的替代方法是将控制器切换功能包装到
    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),因此服务提供程序也可以与服务实例相同的方式在
    配置
    块中声明路由控制器:

    ...
    controller: ctrlFactoryProvider.get('ListController')
    

    由于
    $controller
    不公开已注册控制器的列表,请尝试将其作为自动解决方案,这是人们最不愿意做的事情:除此之外,它是一种黑客攻击,它只会抑制可能的异常并破坏可测性。

    如果我使用$controller作为依赖项注入,这是给未知的提供者:$controllerI在发布这个问题之前已经看到了那个帖子。我也无法访问该服务,因此我尝试直接访问$controller。同样,我也无法访问ControllerChecker服务。:)不要在配置中注入此服务。相反,将其注入根控制器。然后是否可以检查控制器是否存在于.config中?请查看此线程已检查该帖子以及问题中的状态。有一个答案(由@trekforever发布)建议更新角度代码。有没有更好的方法?您无法从配置中访问
    $controller
    。请提供上下文,说明为什么控制器存在时未知。有更好的方法来做你想做的事情,当然不是这样。@estus我已经更新了上下文。从抽象父级进行零更改扩展是OOP中的常见做法,不应该避免。特别是当替代方案不可行时(试试catch$controller很可怕,但其他的更糟糕)。有很多关于角度控制器继承的好方法。我喜欢这种方法。我一定会试试这个,让你知道。谢谢你宝贵的时间。还有一件事。我也在使用带有ng视图的ng路由器。这种做法是否会与之相适应。我的url pattarn类似于列表控制器的/list或编辑控制器的/edit/:id。原始问题中没有提到它,它是一个重要的细节,因为它改变了一切。请参阅更新。