web-dev-qa-db-fra.com

Le contrôleur n'est pas une fonction, indéfini, lors de la définition globale des contrôleurs

J'écris un exemple d'application en utilisant angularjs. J'ai une erreur mentionnée ci-dessous sur le navigateur chrome.

L'erreur est

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

Qui rend comme

L'argument 'ContactController' n'est pas une fonction, eu undefined

Code

<!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>
122
yokks

Avec Angular 1.3+, vous ne pouvez plus utiliser la déclaration de contrôleur global sur la portée globale (sans enregistrement explicite). Vous devrez enregistrer le contrôleur en utilisant la syntaxe module.controller.

Exemple:-

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 = "";

        };
    }]);

ou

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

Il s’agit d’un changement radical mais peut être désactivé pour utiliser des paramètres globaux en utilisant allowGlobals .

Exemple:-

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

Voici le commentaire de Angular source: -

  • vérifier si un contrôleur avec un nom donné est enregistré via $controllerProvider
  • vérifier si l'évaluation de la chaîne sur la portée actuelle renvoie un constructeur
  • si $ controllerProvider # allowGlobals, vérifiez window[constructor] sur l'objet global window (non recommandé).
 .....

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

Quelques vérifications supplémentaires: -

  • Assurez-vous de mettre également le nom de l'application dans la directive ng-app sur votre élément racine angular (par exemple: - html). Exemple: - ng-app = "monApp"

  • Si tout va bien et que le problème persiste, n'oubliez pas de vous assurer que le bon fichier est inclus dans les scripts.

  • Vous n'avez pas défini le même module deux fois à des emplacements différents, ce qui entraîne la suppression des entités définies précédemment sur le même module, Exemple angular.module('app',[]).controller(.., puis à un autre emplacement angular.module('app',[]).service(.. (avec les scripts inclus de bien sûr) peut entraîner l’effacement de la commande précédemment enregistrée sur le module app lors de la deuxième recréation du module.

172
PSL

J'ai eu ce problème parce que j'avais enveloppé un fichier de définition de contrôleur dans une fermeture:

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

Mais j'avais oublié d'invoquer cette fermeture pour exécuter ce code de définition et indiquer à Javascript que mon contrôleur existait. C'est-à-dire que ce qui précède doit être:

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

Notez le () à la fin.

33
rogueleaderr

Je suis un débutant avec Angular et j'ai commis l'erreur fondamentale en n'incluant pas le nom de l'application dans l'élément racine angular. Donc, changer le code de

<html data-ng-app> 

à

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

a travaillé pour moi. @PSL, a déjà couvert cela dans sa réponse ci-dessus.

16
Prakash Tiwari

J'ai eu cette erreur parce que je ne comprenais pas la différence entre angular.module('myApp', []) et angular.module('myApp').

Ceci crée le module 'monApp' et remplace tout module existant nommé 'monApp':

angular.module('myApp', [])

Ceci récupère un module existant 'myApp':

angular.module('myApp')

J'avais écrasé mon module dans un autre fichier, en utilisant le premier appel ci-dessus, ce qui créait un autre module au lieu de le récupérer comme prévu.

Plus de détails ici: https://docs.angularjs.org/guide/module

8
Jake Stewart

Je viens de migrer vers angular 1.3.3 et j'ai constaté que si j'avais plusieurs contrôleurs dans différents fichiers lorsque l'application est remplacée et que je perdais les premiers conteneurs déclarés.

Je ne sais pas si c'est une bonne pratique, mais peut être utile pour une autre.

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

J'ai eu ce problème quand j'ai accidentellement redéclaré myApp:

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

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

Après la redéclare, Controller1 cesse de fonctionner et soulève l'erreur OP.

2
Daniel Flippance

Vraiment bon conseil, sauf que l'erreur MÊME PEUT se produire simplement en manquant le script critique inclus sur votre page racine

exemple:

page: index.html

   np-app="saleApp"

manquant

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

Lorsqu'une Route est informée du contrôleur et de la vue à diffuser:

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

Il est donc essentiel que le problème de contrôleur non défini PEUT survenir dans cette erreur accidentelle de ne pas même référencer le contrôleur!

1
Tom Stickel

Si tout échoue et que vous utilisez Gulp ou quelque chose de similaire, relancez-le!

J'ai perdu 30 minutes en quadruple vérification de tout, alors que tout ce dont j'avais besoin était d'un Swift coup de pied dans le pantalon.

0
sigmapi13

Si vous utilisez des routes (probabilité élevée) et que votre configuration comporte une référence à un contrôleur dans un module qui n'est pas déclaré comme dépendance, l'initialisation peut également échouer.

E.g en supposant que vous avez configuré ngRoute pour votre application, comme

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

Soyez prudent dans le bloc qui déclare les routes,

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

Déclarez secondModule comme dépendance après 'ngRoute' qui devrait résoudre le problème. Je sais que j'ai eu ce problème.

0
H.Rabiee

Ces erreurs sont survenues, dans mon cas, précédées d’erreurs de syntaxe dans list.find () fuction; La méthode 'find' d'une liste non reconnue par IE11 doit donc être remplacée par la méthode Filter, qui fonctionne à la fois pour IE11 et chrome. se référer https://github.com/flrs/visavail/issues/19

0
HydTechie

J'obtenais cette erreur parce que j'utilisais une version plus ancienne de angular qui n'était pas compatible avec mon code.

0
Dean Sha

Cette erreur, dans mon cas, était précédée d'une erreur de syntaxe dans la méthode find d'une liste dans IE11. donc remplacé méthode de recherche par méthode de filtrage comme suggéré https://github.com/flrs/visavail/issues/19

puis au-dessus du contrôleur, l'erreur non définie a été résolue.

0
HydTechie

Cette erreur peut également se produire lorsque vous avez un grand projet avec plusieurs modules. Assurez-vous que l'application (module) utilisée dans votre fichier angular est identique à celle que vous utilisez dans votre modèle, dans cet exemple "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>
0
Patrick