2015-11-20 3 views
3

я могу получить доступ к $ controllerProvider, но не может получить доступ к $ контроллера в следующем методе

angular.module(MODULE_NAME, ['common']) 
    .config(['$routeProvider','$controllerProvider', 
     function($routeProvider, $controllerProvider) { 
     console.log($controllerProvider);//defined 
     console.log($controller);//undefined 
}]); 

Если я использую $ контроллер как инъекции зависимостей, он дает

Unknown provider: $controller 

Но Мне нужно, чтобы получить доступ к нему, как я могу это сделать

EDIT

Мне нужно это, потому что я хочу проверить, что мой контроллер существует. Вот post откуда я использую этот код

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

КОНТЕКСТ

Я создаю архитектуру проекта. Моя структура проекта следующая.

  1. У меня есть один ОБЩИЙ модуль. с ListController, EditController, ViewController
  2. У меня есть некоторые другие модули, такие как MOD1, MOD2 и т. д. с MOD1ListController, MOD1EditController, MOD1ViewController и так далее.
  3. Эти контроллеры, специфичные для модуля, расширяют соответствующий контроллер от общего модуля.

Теперь мой план, а новый модуль (MODX) должен быть разработан, а затем, если есть некоторые дополнительные функции, то только разработчик создаст новый MODXListController для этого модуля по наследованию общей ListController. В противном случае им не нужно ничего создавать.

Таким образом, система проверит, содержит ли этот модуль MODXListController или нет. Если нет, система будет использовать Common ListController.

Я не хочу создавать MODXListController, который наследует обычный ListController, но не делает никаких дополнительных изменений. Потому что у меня много модулей почти 25, и все они в основном используют одну и ту же функциональность.

+0

вы не можете получить доступ к '$ controller' из своей конфигурации. –

+0

Укажите, почему именно неизвестно, существует ли контроллер. Есть лучшие способы делать то, что вы пытаетесь сделать, конечно, не так. – estus

+0

@estus Я обновил контекст. –

ответ

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 не раскрывает список зарегистрированных контроллеров, при попытке захвата это приходит в голову как автоматическое решение, и это последнее, что можно сделать: кроме того, это взломать, он просто подавляет возможные исключения и повреждения проверяемость.

+0

Мне нравится этот подход. Я обязательно попробую это и дам вам знать. Спасибо за ваше драгоценное время. –

+0

Еще одна вещь. Я также использую ng-router с ng-view. Подойдет ли этот подход. Мой url pattarn похож на/list для контроллера списка или/edit /: id для контроллера редактирования. –

+1

Не было упомянуто в оригинальном вопросе, и это важная деталь, потому что она меняет все. См. Обновление. – estus

0

В .config вы можете использовать поставщиков (например, $ routeProvider).

В .run вы можете использовать только экземпляры служб (например, $ route).

$ контроллер имеет сервис типа, который не может быть использован в .config.

Более подробно об этом читайте here.

Подробное обсуждение на переполнение стека на this нить показывает, что может быть введен в другие.

+0

Тогда можно ли проверить, что контроллер существует или нет в .config? –

+0

Посмотрите эту тему http://stackoverflow.com/questions/19734565/how-to-check-if-an-angularjs-controller-has-been-defined –

+0

Уже проверено это сообщение, а также вопрос в вопросе. Существует ответ (отправленный @trekforever), который предлагает обновить угловой код. Есть ли лучший способ? –

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) функцию, чтобы проверить, определен ли ваш контроллер или нет.

+0

Если я использую $ controller как инъекцию зависимости, он дает Неизвестный поставщик: $ controller –

+0

Я уже видел это сообщение, прежде чем публиковать этот вопрос. Я также не могу получить доступ к этой службе, поэтому я попытался получить доступ к $ controller напрямую. –

+0

Точно так же я не могу получить доступ к службе ControllerChecker. :) –

Смежные вопросы