2013-11-01 4 views
9

У меня есть приложение, определенное таким образом:Как проверить, если angularjs контроллер был определен

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

Контроллеры определяются следующим образом:

angular.module("myApp") 
    .controller("myController", function ($scope) { ... }); 

Как я могу определить isControllerDefined() (в приведенной выше конфигурации), чтобы проверить, существует ли данный контроллер, если у меня есть имя контроллера? Я чувствую, что я должен быть в состоянии сделать что-то вроде одного из них:

var ctrl = angular.module("myApp").getController("myController"); 
var ctrl = $controllerProvider.get("myController"); 

или что-то в этом роде ... но я не могу найти какой-либо функциональности для этого. Помогите?

+2

Просто любопытно, что нужно проверить, если контроллер зарегистрирован является. – dtabuenc

+1

К сожалению, я не помню сейчас (почти год спустя). Я * думаю * Я, возможно, занимался разработкой проекта и хотел, чтобы интроспекция облегчала документацию. Я подтвердил ваш комментарий, потому что вы не просто предположили, что это было не так, как хотелось бы (я ненавижу это). –

ответ

9

Пример службы, которая может проверить, существует ли контроллер. Обратите внимание, что он ищет global function с указанным именем, а также контроллер в провайдере $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); 
     } 
    } 
    }; 
}]); 

См. the fiddle для использования.

+0

Должен ли кто-нибудь проверять контроллер *** после *** фактического контроллера он проверяет? –

+0

Что такое проверка для 'TypeError'? В чем смысл? – Vadorequest

+0

См. Комментарий GlennFilson для ответа ниже. Когда зависимости для контроллера не могут быть предоставлены, вызывается TypeError. Это может произойти, например, при попытке создать «нормальную» функцию в качестве контроллера. – fracz

2

В настоящее время нет простого способа получить список контроллеров. Это скрыто только для внутреннего использования. Вы должны пойти к исходному коду и добавить публичный метод, которые возвращают внутреннюю переменную контроллеры (в функции $ ControllerProvider) https://github.com/angular/angular.js/blob/master/src/ng/controller.js#L16

this.getControllers = function() { 
    return controllers; 
    // This will return an object of all the currently defined controllers 
    }; 

Тогда вы можете просто

app.config(function($controllerProvider) { 
    var myCtrl = $controllerProvider.getControllers()['myController']; 
}); 
2

Вы можете использовать службу $ controller и сделать $ controller ('myController') и обернуть пробную арку вокруг нее, чтобы вы знали, не сработает ли она.

+2

Это не отличное решение, так как существует множество причин, по которым $ controller может вызывать исключение. Например, не зная, какие специальные зависимости может иметь контроллер, если эти зависимости не предоставляются, будет выбрано исключение. –

+0

Однако вы все равно сможете сказать, что такое конкретное исключение, и решить, что делать дальше. – dtabuenc

6

Я натолкнулся на эту ту же самую проблему на днях. У меня было несколько проблем с принятым в настоящее время ответ, а именно потому, что один из моих контроллеров выполнял вызов инициализации к серверу при конкретизации для заполнения некоторых данных (то есть):

function ExampleController($scope, ExampleService) { 
    ExampleService.getData().then(function(data) { 
     $scope.foo = data.foo; 
     $scope.bar = data.bar 
    }); 
} 

Как можно заметить, в настоящее время принято ответ будет фактически создавать экземпляр контроллера, прежде чем отбрасывать его. Это приводит к появлению нескольких вызовов API по каждому запросу (один для проверки наличия контроллера, который фактически использует контроллер).

У меня было немного окунуться в $controllersource code и обнаружил, что есть недокументированный параметр, который вы можете передать в вызванном 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; 
      } 
     } 
    }; 
}]); 

UPDATE: Возможно, намного проще, как декоратор:

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; 
    }]); 
}]); 

Тогда вы можете просто впрыснуть $controller и называем exists(...)

function($controller) { 
    console.log($controller.exists('TestController') ? 'Exists' : 'Does not exist'); 
} 
3

С угловой 1.5.1(еще не выпущен на время написания), есть новый способ проверить, существует ли контроллер или n через метод $ControllerProvider.has('MyCtrlName').

Github вопрос: https://github.com/angular/angular.js/issues/13951

Github PR: https://github.com/angular/angular.js/pull/14109

Фиксировать портированном в 1.5.1 непосредственно: https://github.com/angular/angular.js/commit/bb9575dbd3428176216355df7b2933d2a72783cd


Отказ от ответственности: Поскольку многие люди интересовались этой характеристикой, я сделал PR, потому что мне также нужно, чтобы это были некоторые из моих проектов. Удачи! :)

Это PR было основано на @trekforever ответ, спасибо за подсказку :)

+0

У меня есть еще один вопрос с угловыми вопросами. Вы хотите прокомментировать это? Пользователь, который отправил ответ, взлетел без разработки. Вот ссылка: http://stackoverflow.com/questions/35588344/how-do-i-connect-this-interval-service-to-a-view – CodeMed

+0

К сожалению, в то время не было вашего вопроса. Рад, что вы нашли свой ответ :) – Vadorequest

+0

@ Vadorequest, приятно! кто использует это, не забывайте $ controllerProvider (lowerCase c) – bleuscyther

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