Le contrôleur n'est pas une fonction, n'est pas défini, tout en définissant les contrôleurs globalement

123

J'écris un exemple d'application en utilisant angularjs. J'ai eu 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, n'est pas défini

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>
yokks
la source

Réponses:

172

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

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

C'est un changement radical, mais il peut être désactivé pour utiliser des globaux en utilisantallowGlobals .

Exemple:-

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

Voici le commentaire de la source angulaire: -

  • 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
  • if $ controllerProvider # allowGlobals, vérifiez window[constructor]l' windowobjet global (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 ng-appdirective sur votre élément racine angulaire (par exemple: - html). Exemple: - ng-app = "myApp"

  • Si tout va bien et que vous rencontrez toujours le problème, 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 endroits différents, ce qui entraîne l'effacement des entités définies précédemment sur le même module.Exemple angular.module('app',[]).controller(..et à nouveau dans un autre endroit angular.module('app',[]).service(..(avec les deux scripts inclus bien sûr) peuvent entraîner le contrôleur précédemment enregistré sur le module appà effacer avec la deuxième recréation du module.

PSL
la source
Comment vérifier cela comme suggéré? vérifier si un contrôleur avec un nom donné est enregistré via $ controllerProvider
geckob
app.register.controller ('TheController', TheController); a fait l'affaire pour moi.
morph85
33

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'appeler cette fermeture pour exécuter ce code de définition et dire à Javascript que mon contrôleur existait. Par exemple, ce qui précède doit être:

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

Notez le () à la fin.

rogueleaderr
la source
1
+1 Fait intéressant, il semble que Visual Studio supprime parfois automatiquement l'invocation. J'ai copié un fichier js existant contenant ce code; l'original avait l'appel, le fichier copié n'en avait pas.
papergodzilla
16

Je suis un débutant avec Angular et j'ai fait l'erreur de base de ne pas inclure le nom de l'application dans l'élément racine angulaire. Donc, changer le code de

<html data-ng-app> 

à

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

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

Prakash Tiwari
la source
8

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

Cela crée le module 'myApp' et écrase tout module existant nommé 'myApp':

angular.module('myApp', [])

Cela 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 qui a créé un autre module au lieu de le récupérer comme je m'y attendais.

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

Jake Stewart
la source
1
Dans mon cas, j'ai ajouté le module, j'ai ajouté le contrôleur, mais j'ai oublié d'ajouter le module dans la liste des modules de l'application. `angular.module (" app ", [HEREYOURMODULE] ...`
Thomas
3

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 j'ai perdu les premiers conteneurs déclarés.

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

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

J'ai eu ce problème lorsque 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 nouvelle déclaration, Controller1cesse de fonctionner et soulève l'erreur OP.

Daniel Flippance
la source
2

Vraiment un excellent conseil, sauf que la MÊME erreur 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 à servir:

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

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

Tom Stickel
la source
0

Cette erreur peut également se produire lorsque vous avez un grand projet avec de nombreux modules. Assurez-vous que l'application (module) utilisée dans votre fichier angulaire est la même que 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>
Patrick
la source
0

Si tout le reste échoue et que vous utilisez Gulp ou quelque chose de similaire ... réexécutez-le!

J'ai perdu 30 minutes en quadruple à tout vérifier alors qu'il ne manquait qu'un coup de pied rapide dans le pantalon.

sigmapi13
la source
0

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

Par exemple, en supposant que vous ayez 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éclarer secondModulecomme une dépendance après «ngRoute» devrait résoudre le problème. Je sais que j'ai eu ce problème.

H.Rabiee
la source
0

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

Dean Sha
la source
0

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

HydTechie
la source
0

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

puis au-dessus du contrôleur non défini l'erreur résolue.

HydTechie
la source
-3

J'ai eu la même erreur en suivant un ancien tutoriel avec (pas assez vieux) AngularJS 1.4.3. La solution de loin la plus simple est d'éditer la source angular.js depuis

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

à

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

et suivez simplement le tutoriel tel quel, et les fonctions globales obsolètes fonctionnent simplement comme des contrôleurs.

MKaama
la source
C'est une mauvaise pratique. Comme mentionné dans la réponse de PSL, vous pouvez le faire de cette façon:angular.module('app') .config(['$controllerProvider', function($controllerProvider) { $controllerProvider.allowGlobals(); }]);
gm2008
-1. C'est aussi un excellent moyen de vous assurer que (a) vous écrasez ceci dès que vous mettez à niveau, ce qui générera des rapports inutiles (et incorrects) que "la mise à jour de la 1.4.3 vers la 1.4.4 a cassé mon application!" et / ou (b) vous ne mettez pas à jour votre application parce que "c'est difficile".
Phillip Copley