El controlador no es una función, quedó indefinido al definir controladores globalmente
Estoy escribiendo una aplicación de muestra usando angularjs. Recibí el error que se menciona 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%20undefinido
Lo 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>
Con Angular 1.3+ ya no puede utilizar la declaración de controlador global en el ámbito global (sin registro explícito). Necesitará registrar el controlador usando module.controller
la sintaxis.
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 importante, pero se puede desactivar para usar globales usandoallowGlobals
.
Ejemplo:-
angular.module('app')
.config(['$controllerProvider', function($controllerProvider) {
$controllerProvider.allowGlobals();
}]);
Aquí está el comentario de la fuente Angular: -
- comprobar si un controlador con nombre de pila está registrado a través de
$controllerProvider
- comprobar si la evaluación de la cadena en el alcance actual devuelve un constructor
- si $controllerProvider#allowGlobals, verifique
window[constructor]
el objeto globalwindow
(no recomendado)
.....
expression = controllers.hasOwnProperty(constructor)
? controllers[constructor]
: getter(locals.$scope, constructor, true) ||
(globals ? getter($window, constructor, true) : undefined);
Algunas comprobaciones adicionales: -
Asegúrese de poner también el nombre de la aplicación en
ng-app
la directiva en su elemento raíz angular (por ejemplo:-) .html
Ejemplo:- ng-app="miAplicación"Si todo está bien y el problema persiste, recuerde asegurarse de tener el archivo correcto incluido en los scripts.
No ha definido el mismo módulo dos veces en diferentes lugares, lo que da como resultado que se borre cualquier entidad definida previamente en el mismo módulo. Ejemplo
angular.module('app',[]).controller(..
y nuevamente en otro lugarangular.module('app',[]).service(..
(con ambos scripts incluidos, por supuesto) puede causar que el controlador previamente registrado en el móduloapp
que se borrará con la segunda recreación del módulo.
Tuve este problema porque había envuelto un archivo de definición de controlador en un cierre:
(function() {
...stuff...
});
Pero me había olvidado de 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.
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
Acabo de migrar a angular 1.3.3 y descubrí que si tenía varios controladores en diferentes archivos cuando se anula la aplicación y perdía los primeros contenedores declarados.
No sé si es una buena práctica, pero tal vez pueda resultar útil para otra.
var app = app;
if(!app) {
app = angular.module('web', ['ui.bootstrap']);
}
app.controller('SearchCtrl', SearchCtrl);
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 de la redeclaración, Controller1
deja de funcionar y genera el error OP.