O controlador não é uma função, ficou indefinido, enquanto definia controladores globalmente


123

Estou escrevendo um aplicativo de exemplo usando angularjs. Eu recebi um erro mencionado abaixo no navegador Chrome.

O erro é

Erro: [ng: areq] http://errors.angularjs.org/1.3.0-beta.17/ng/areq?p0=ContactController&p1=not%20a%20function%2C%20got%20undefined

O que renderiza como

O argumento 'ContactController' não é uma função, ficou indefinido

Código

<!DOCTYPE html>
<html ng-app>
<head>
    <script src="../angular.min.js"></script>
    <script type="text/javascript">
        function ContactController($scope) {
            $scope.contacts = ["abcd@gmail.com", "abcd@yahoo.co.in"];

            $scope.add = function() {
                $scope.contacts.push($scope.newcontact);
                $scope.newcontact = "";                 
            };
        }    
    </script>    
</head>

<body>    
    <h1>  modules sample </h1>

    <div ng-controller="ContactController">
        Email:<input type="text" ng-model="newcontact">
        <button ng-click="add()">Add</button>

        <h2> Contacts </h2>
        <ul>
            <li ng-repeat="contact in contacts"> {{contact}} </li>
        </ul>    
    </div>
</body> 
</html>

Respostas:


172

Com o Angular 1.3+, você não pode mais usar a declaração global do controlador no escopo global (sem registro explícito). Você precisaria registrar o controlador usando a module.controllersintaxe.

Exemplo:-

angular.module('app', [])
    .controller('ContactController', ['$scope', function ContactController($scope) {
        $scope.contacts = ["abcd@gmail.com", "abcd@yahoo.co.in"];

        $scope.add = function() {
            $scope.contacts.push($scope.newcontact);
            $scope.newcontact = "";

        };
    }]);

ou

function ContactController($scope) {
    $scope.contacts = ["abcd@gmail.com", "abcd@yahoo.co.in"];

    $scope.add = function() {
        $scope.contacts.push($scope.newcontact);
        $scope.newcontact = "";
    };
}
ContactController.$inject = ['$scope'];
angular.module('app', []).controller('ContactController', ContactController);

É uma mudança de última hora, mas pode ser desativada para usar globais usandoallowGlobals .

Exemplo:-

angular.module('app')
    .config(['$controllerProvider', function($controllerProvider) {
        $controllerProvider.allowGlobals();
    }]);

Aqui está o comentário da fonte Angular: -

  • verifique se um controlador com nome determinado está registrado via $controllerProvider
  • verifique se a avaliação da sequência no escopo atual retorna um construtor
  • se $ controllerProvider # allowGlobals, verifique window[constructor]o windowobjeto global (não recomendado)
 .....

expression = controllers.hasOwnProperty(constructor)
            ? controllers[constructor]
            : getter(locals.$scope, constructor, true) ||
                (globals ? getter($window, constructor, true) : undefined);

Algumas verificações adicionais: -

  • Certifique-se de colocar o nome do aplicativo na ng-appdiretiva em seu elemento raiz angular (por exemplo: - html) também. Exemplo: - ng-app = "myApp"

  • Se tudo estiver bem e você ainda estiver recebendo o problema, lembre-se de ter o arquivo correto incluído nos scripts.

  • Você não definiu o mesmo módulo duas vezes em locais diferentes, o que resulta na eliminação de quaisquer entidades definidas anteriormente no mesmo módulo. Exemplo angular.module('app',[]).controller(..e novamente em outro local angular.module('app',[]).service(..(com os dois scripts incluídos, é claro) pode causar o controlador registrado anteriormente no módulo appa ser limpo com a segunda recriação do módulo.


Como verificar isso como sugerido? verifique se um controlador com nome determinado está registrado via $ controllerProvider
geckob

app.register.controller ('TheController', TheController); fez o truque para mim.
morph85

33

Eu obtive esse problema porque envolvi um arquivo de definição de controlador em um fechamento:

(function() {
   ...stuff...
});

Mas eu tinha esquecido de realmente invocar esse fechamento para executar esse código de definição e realmente dizer ao Javascript que meu controlador existia. Ou seja, o acima precisa ser:

(function() {
   ...stuff...
})();

Observe o () no final.


1
+1 Curiosamente, parece que o visual studio às vezes remove automaticamente a invocação. Copiei um arquivo js existente contendo esse código; o original teve a invocação, o arquivo copiado não.
Papergodzilla

16

Sou iniciante no Angular e cometi o erro básico de não incluir o nome do aplicativo no elemento raiz angular. Então, alterando o código de

<html data-ng-app> 

para

<html data-ng-app="myApp"> 

trabalhou para mim. O @PSL já cobriu isso em sua resposta acima.


8

Eu tive esse erro porque não entendi a diferença entre angular.module('myApp', [])eangular.module('myApp') .

Isso cria o módulo 'myApp' e substitui qualquer módulo existente chamado 'myApp':

angular.module('myApp', [])

Isso recupera um módulo existente 'myApp':

angular.module('myApp')

Eu estava substituindo meu módulo em outro arquivo, usando a primeira chamada acima, que criou outro módulo, em vez de recuperar como eu esperava.

Mais detalhes aqui: https://docs.angularjs.org/guide/module


1
No meu caso, adicionei o módulo, adicionei o controlador, mas esqueci de adicioná-lo na lista de módulos do aplicativo. `angular.module (" app ", [HEREYOURMODULE] ...`
Thomas

3

Acabei de migrar para o angular 1.3.3 e descobri que se eu tivesse vários controladores em arquivos diferentes quando o aplicativo é substituído e perdi os primeiros contêineres declarados.

Não sei se é uma boa prática, mas talvez possa ser útil para outra.

var app = app;
if(!app) {
    app = angular.module('web', ['ui.bootstrap']);
}
app.controller('SearchCtrl', SearchCtrl);

2

Eu tive esse problema quando redeclarou acidentalmente myApp:

var myApp = angular.module('myApp',[...]);
myApp.controller('Controller1', ...);

var myApp = angular.module('myApp',[...]);
myApp.controller('Controller2', ...);

Após a redeclaração, Controller1para de funcionar e gera o erro OP.


2

Realmente ótimo conselho, exceto que o MESMO erro PODE ocorrer simplesmente por falta do script crítico incluído na sua página raiz

exemplo:

página: index.html

   np-app="saleApp"

Ausência de

<script src="./ordersController.js"></script>

Quando uma Rota é informada sobre qual controlador e exibição servir:

 .when('/orders/:customerId', {
     controller: 'OrdersController',
     templateUrl: 'views/orders.html'
 })

Tão essencial que a questão indefinida do controlador PODE ocorrer neste erro acidental de nem mesmo fazer referência ao controlador!


0

Este erro também pode ocorrer quando você tem um projeto grande com muitos módulos. Verifique se o aplicativo (módulo) usado no seu arquivo angular é o mesmo que você usa no seu modelo, neste exemplo " thisApp ".

app.js

angular
.module('thisApp', [])
    .controller('ContactController', ['$scope', function ContactController($scope) {
        $scope.contacts = ["abcd@gmail.com", "abcd@yahoo.co.in"];

        $scope.add = function() {
            $scope.contacts.push($scope.newcontact);
            $scope.newcontact = "";

        };
    }]);

index.html

  <html>
    <body ng-app='thisApp' ng-controller='ContactController>
         ...
        <script type="text/javascript" src="assets/js/angular.js"></script>
        <script src="app.js"></script>
    </body>
    </html>

0

Se tudo mais falhar e você estiver usando o Gulp ou algo semelhante ... basta executá-lo novamente!

Perdi 30 minutos quadruplicando tudo quando tudo o que precisava era de um chute rápido nas calças.


0

Se você estiver usando rotas (alta probabilidade) e sua configuração tiver uma referência a um controlador em um módulo que não seja declarado como dependência, a inicialização poderá falhar também.

Por exemplo, supondo que você configurou o ngRoute para seu aplicativo, como

angular.module('yourModule',['ngRoute'])
.config(function($routeProvider, $httpProvider) { ... });

Tenha cuidado no bloco que declara as rotas,

.when('/resourcePath', { 
templateUrl: 'resource.html',
controller: 'secondModuleController' //lives in secondModule
});

Declarar secondModulecomo uma dependência após o 'ngRoute' deve resolver o problema. Eu sei que tive esse problema.


0

Eu estava recebendo esse erro porque estava usando uma versão mais antiga do angular que não era compatível com o meu código.


0

Esses erros ocorreram, no meu caso, precedidos por erros de sintaxe no list.find () fuction; O método 'find' de uma lista não reconhecida pelo IE11, portanto, deve ser substituído pelo método Filter, que funciona para o IE11 e o chrome. consulte https://github.com/flrs/visavail/issues/19


0

Este erro, no meu caso, precedido por erro de sintaxe no método find de uma lista no IE11. método de localização substituído por método de filtro, conforme sugerido https://github.com/flrs/visavail/issues/19

então, o erro acima do controlador não definido foi resolvido.


-3

Eu recebi o mesmo erro ao seguir um tutorial antigo com o AngularJS 1.4.3 (não o suficiente). De longe, a solução mais simples é editar a fonte angular.js de

function $ControllerProvider() {
  var controllers = {},
      globals = false;

para

function $ControllerProvider() {
  var controllers = {},
      globals = true;

e siga o tutorial como está e as funções globais descontinuadas funcionam como controladoras.


Isso é uma má prática. Conforme mencionado na resposta da PSL, você pode fazer o seguinte:angular.module('app') .config(['$controllerProvider', function($controllerProvider) { $controllerProvider.allowGlobals(); }]);
gm2008 28/08

-1. Essa também é uma ótima maneira de garantir que (a) você a substitua assim que atualizar, o que gerará relatórios desnecessários (e incorretos) de que "a atualização 1.4.3 para 1.4.4 interrompeu meu aplicativo!" e / ou (b) você não atualiza seu aplicativo porque "é difícil".
Phillip Copley
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.