El controlador no es una función, se definió indefinidamente y definió los controladores globalmente

123

Estoy escribiendo una aplicación de muestra usando angularjs. Recibí un error mencionado a continuación en el navegador Chrome.

El error es

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

Que se presenta como

El argumento 'ContactController' no es una función, quedó indefinido

Código

<!DOCTYPE html>
<html ng-app>
<head>
    <script src="../angular.min.js"></script>
    <script type="text/javascript">
        function ContactController($scope) {
            $scope.contacts = ["[email protected]", "[email protected]"];

            $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>
yokks
fuente

Respuestas:

172

Con Angular 1.3+ ya no puede usar la declaración de controlador global en el ámbito global (Sin registro explícito). Debería registrar el controlador utilizando la module.controllersintaxis.

Ejemplo:-

angular.module('app', [])
    .controller('ContactController', ['$scope', function ContactController($scope) {
        $scope.contacts = ["[email protected]", "[email protected]"];

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

        };
    }]);

o

function ContactController($scope) {
    $scope.contacts = ["[email protected]", "[email protected]"];

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

Es un cambio innovador, pero se puede desactivar para usar globales utilizandoallowGlobals .

Ejemplo:-

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

Aquí está el comentario de la fuente angular: -

  • verificar si un controlador con nombre de pila está registrado a través de $controllerProvider
  • compruebe si la evaluación de la cadena en el ámbito actual devuelve un constructor
  • if $ controllerProvider # allowGlobals, verifique window[constructor]el windowobjeto global (no recomendado)
 .....

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

Algunas verificaciones adicionales: -

  • Asegúrese de poner el nombre de la aplicación en la ng-appdirectiva en su elemento raíz angular (por ejemplo: - html) también. Ejemplo: - ng-app = "myApp"

  • Si todo está bien y todavía tiene el problema, recuerde asegurarse de tener el archivo correcto incluido en los scripts.

  • No se ha definido el mismo módulo dos veces en diferentes lugares que los resultados en las entidades definidas previamente en el mismo módulo que se limpiaron, Ejemplo angular.module('app',[]).controller(..y de nuevo en otro lugar angular.module('app',[]).service(..(tanto con los guiones incluidos por supuesto) puede hacer que el controlador registrado previamente en el módulo appque se eliminará con la segunda recreación del módulo.

PSL
fuente
¿Cómo verificar esto como se sugiere? verificar si un controlador con nombre de pila está registrado a través de $ controllerProvider
geckob
app.register.controller ('TheController', TheController); hizo el truco para mí
morph85
33

Recibí este problema porque había envuelto un archivo de definición de controlador en un cierre:

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

Pero había olvidado invocar ese cierre para ejecutar ese código de definición y decirle a Javascript que mi controlador existía. Es decir, lo anterior debe ser:

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

Tenga en cuenta el () al final.

rogueleaderr
fuente
1
+1 Curiosamente, parece que Visual Studio a veces elimina automáticamente la invocación. Copié un archivo js existente que contiene este código; el original tenía la invocación, el archivo copiado no.
papergodzilla
16

Soy un principiante con Angular y cometí el error básico de no incluir el nombre de la aplicación en el elemento raíz angular. Entonces, cambiando el código de

<html data-ng-app> 

a

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

trabajó para mi. @PSL, ya ha cubierto esto en su respuesta anterior.

Prakash Tiwari
fuente
8

Tuve este error porque no entendí la diferencia entre angular.module('myApp', [])y angular.module('myApp').

Esto crea el módulo 'myApp' y sobrescribe cualquier módulo existente llamado 'myApp':

angular.module('myApp', [])

Esto recupera un módulo existente 'myApp':

angular.module('myApp')

Había estado sobrescribiendo mi módulo en otro archivo, usando la primera llamada anterior que creó otro módulo en lugar de recuperarlo como esperaba.

Más detalles aquí: https://docs.angularjs.org/guide/module

Jake Stewart
fuente
1
En mi caso, agregué el módulo, agregué el controlador, pero olvidé agregar el módulo en la lista de módulos para la aplicación. `angular.module (" aplicación ", [HEREYOURMODULE] ...`
Thomas
3

Acabo de migrar a angular 1.3.3 y descubrí que si tenía varios controladores en diferentes archivos cuando la aplicación se anula y perdí los primeros contenedores declarados.

No sé si es una buena práctica, pero tal vez pueda ser útil para otra.

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

Tuve este problema cuando accidentalmente volví a declarar myApp:

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

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

Después del redeclare, Controller1deja de funcionar y genera el error OP.

Daniel Flippance
fuente
2

Realmente un excelente consejo, excepto que el MISMO error PUEDE ocurrir simplemente por faltar el script crítico que se incluye en su página raíz

ejemplo:

página: index.html

   np-app="saleApp"

Desaparecido

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

Cuando se le dice a una ruta qué controlador y qué vista debe servir:

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

¡Tan esencial que el problema del controlador indefinido PUEDE ocurrir en este error accidental de ni siquiera hacer referencia al controlador!

Tom Stickel
fuente
0

Este error también puede ocurrir cuando tiene un proyecto grande con muchos módulos. Asegúrese de que la aplicación (módulo) utilizada en su archivo angular es la misma que utiliza en su plantilla, en este ejemplo " thisApp ".

app.js

angular
.module('thisApp', [])
    .controller('ContactController', ['$scope', function ContactController($scope) {
        $scope.contacts = ["[email protected]", "[email protected]"];

        $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>
Patricio
fuente
0

Si todo lo demás falla y está usando Gulp o algo similar ... ¡simplemente vuelva a ejecutarlo!

Perdí 30 minutos cuádruple comprobando todo cuando todo lo que necesitaba era una patada rápida en los pantalones.

sigmapi13
fuente
0

Si está utilizando rutas (alta probabilidad) y su configuración tiene una referencia a un controlador en un módulo que no se declara como dependencia, entonces la inicialización también puede fallar.

Por ejemplo, suponiendo que haya configurado ngRoute para su aplicación, como

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

Tenga cuidado en el bloque que declara las rutas,

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

Declarar secondModulecomo dependencia después de 'ngRoute' debería resolver el problema. Sé que tuve este problema.

H.Rabiee
fuente
0

Recibí este error porque estaba usando una versión anterior de angular que no era compatible con mi código.

Dean Sha
fuente
0

Estos errores ocurrieron, en mi caso, precedidos por errores de sintaxis en la función list.find (); El método 'find' de una lista no reconocida por IE11, por lo que debe reemplazarse por el método Filter, que funciona tanto para IE11 como para Chrome. consulte https://github.com/flrs/visavail/issues/19

HydTechie
fuente
0

Este error, en mi caso, precedido por un error de sintaxis en el método find de una lista en IE11. reemplazado método de búsqueda por método de filtro como se sugiere https://github.com/flrs/visavail/issues/19

entonces el controlador anterior no definió el error resuelto.

HydTechie
fuente
-3

Obtuve el mismo error al seguir un tutorial anterior con (no lo suficientemente viejo) AngularJS 1.4.3. Con mucho, la solución más simple es editar la fuente angular.js de

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

a

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

y solo siga el tutorial tal cual, y las funciones globales obsoletas solo funcionan como controladores.

Makama
fuente
Esta es una mala práctica. Como se menciona en la respuesta de PSL, puede hacerlo de esta manera:angular.module('app') .config(['$controllerProvider', function($controllerProvider) { $controllerProvider.allowGlobals(); }]);
gm2008
-1. Esta también es una excelente manera de asegurarse de que (a) sobrescriba esto tan pronto como actualice, lo que generará informes innecesarios (e incorrectos) de que "la actualización 1.4.3 a 1.4.4 rompió mi aplicación". y / o (b) no actualiza su aplicación porque "es difícil".
Phillip Copley