El controlador no es una función, quedó indefinido al definir controladores globalmente

Resuelto yokks asked hace 10 años • 14 respuestas

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>
yokks avatar Aug 04 '14 11:08 yokks
Aceptado

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.controllerla 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 global window(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-appla directiva en su elemento raíz angular (por ejemplo:-) . htmlEjemplo:- 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 lugar angular.module('app',[]).service(..(con ambos scripts incluidos, por supuesto) puede causar que el controlador previamente registrado en el módulo appque se borrará con la segunda recreación del módulo.

PSL avatar Aug 04 '2014 04:08 PSL

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.

rogueleaderr avatar Jun 23 '2015 06:06 rogueleaderr

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 avatar Feb 02 '2016 05:02 Jake Stewart

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);
Franzi avatar Nov 24 '2014 22:11 Franzi

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, Controller1deja de funcionar y genera el error OP.

Daniel Flippance avatar May 18 '2016 06:05 Daniel Flippance