Controller ist keine Funktion, wurde undefiniert, während Controller global definiert wurden

123

Ich schreibe eine Beispielanwendung mit anglejs. Ich habe einen Fehler im Chrome-Browser.

Fehler ist

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

Welches rendert als

Das Argument 'ContactController' ist keine Funktion, wurde undefiniert

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
quelle

Antworten:

172

Mit Angular 1.3+ können Sie die globale Controller-Deklaration nicht mehr für den globalen Bereich verwenden (ohne explizite Registrierung). Sie müssten den Controller mithilfe der module.controllerSyntax registrieren .

Beispiel:-

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

        };
    }]);

oder

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 ist eine bahnbrechende Änderung, aber es kann deaktiviert werden, um Globals zu verwendenallowGlobals .

Beispiel:-

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

Hier ist der Kommentar von Angular Quelle: -

  • Überprüfen Sie, ob ein Controller mit Vorname über registriert ist $controllerProvider
  • Überprüfen Sie, ob die Auswertung der Zeichenfolge im aktuellen Bereich einen Konstruktor zurückgibt
  • Wenn $ controllerProvider # allowGlobals, überprüfen Sie window[constructor]das globale windowObjekt (nicht empfohlen).
 .....

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

Einige zusätzliche Überprüfungen: -

  • Stellen Sie sicher, dass Sie den App-Namen auch in die ng-appDirektive Ihres eckigen Stammelements einfügen (z. B.: - html). Beispiel: - ng-app = "myApp"

  • Wenn alles in Ordnung ist und das Problem weiterhin auftritt, stellen Sie sicher, dass die Skripte die richtige Datei enthalten.

  • Sie haben dasselbe Modul nicht zweimal an verschiedenen Stellen definiert, was dazu führt, dass zuvor auf demselben Modul definierte Entitäten gelöscht werden. Beispiel angular.module('app',[]).controller(..und erneut an einer anderen Stelle angular.module('app',[]).service(..(wobei natürlich beide Skripte enthalten sind) können dazu führen, dass der zuvor registrierte Controller auf dem Modul Modul app, das mit der zweiten Neuerstellung des Moduls gelöscht werden soll.

PSL
quelle
Wie kann ich dies wie vorgeschlagen überprüfen? Überprüfen Sie, ob ein Controller mit Vornamen über $ controllerProvider
geckob
app.register.controller ('TheController', TheController); hat den Trick für mich gemacht.
Morph85
33

Ich habe dieses Problem erhalten, weil ich eine Controller-Definitionsdatei in einen Abschluss eingeschlossen hatte:

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

Aber ich hatte vergessen, diesen Abschluss tatsächlich aufzurufen, um diesen Definitionscode auszuführen und Javascript tatsächlich mitzuteilen, dass mein Controller existiert. Das heißt, das Obige muss sein:

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

Beachten Sie das () am Ende.

rogueleaderr
quelle
1
+1 Interessanterweise scheint Visual Studio den Aufruf manchmal automatisch zu entfernen. Ich habe eine vorhandene js-Datei kopiert, die diesen Code enthält. Das Original hatte den Aufruf, die kopierte Datei nicht.
Papergodzilla
16

Ich bin ein Anfänger mit Angular und habe den grundlegenden Fehler gemacht, den App-Namen nicht in das Angular-Root-Element aufzunehmen. Also, den Code von ändern

<html data-ng-app> 

zu

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

arbeitete für mich. @PSL, hat dies bereits in seiner obigen Antwort behandelt.

Prakash Tiwari
quelle
8

Ich hatte diesen Fehler, weil ich den Unterschied zwischen angular.module('myApp', [])und nicht verstanden habe angular.module('myApp').

Dadurch wird das Modul 'myApp' erstellt und jedes vorhandene Modul mit dem Namen 'myApp' überschrieben:

angular.module('myApp', [])

Dadurch wird ein vorhandenes Modul 'myApp' abgerufen :

angular.module('myApp')

Ich hatte mein Modul in einer anderen Datei überschrieben und den ersten Aufruf oben verwendet, bei dem ein anderes Modul erstellt wurde, anstatt es wie erwartet abzurufen.

Weitere Details hier: https://docs.angularjs.org/guide/module

Jake Stewart
quelle
1
In meinem Fall habe ich das Modul hinzugefügt, ich habe den Controller hinzugefügt, aber ich habe vergessen, das Modul in der Liste der Module für die App hinzuzufügen. `angle.module (" app ", [HEREYOURMODULE] ...`
Thomas
3

Ich habe gerade auf Angular 1.3.3 migriert und festgestellt, dass ich mehrere Controller in verschiedenen Dateien hatte, wenn die App überschrieben wurde und ich zuerst deklarierte Container verloren habe.

Ich weiß nicht, ob es eine gute Praxis ist, aber vielleicht kann sie für eine andere hilfreich sein.

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

Ich hatte dieses Problem, als ich versehentlich neu deklarierte myApp:

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

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

Stört nach der erneuten Deklaration nicht Controller1mehr und löst den OP-Fehler aus.

Daniel Flippance
quelle
2

Wirklich gute Ratschläge, außer dass der gleiche Fehler einfach dadurch auftreten kann , dass das kritische Skript auf Ihrer Stammseite fehlt

Beispiel:

Seite: index.html

   np-app="saleApp"

Vermisst

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

Wenn einer Route mitgeteilt wird, welcher Controller und welche Ansicht zu bedienen sind:

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

Daher kann das undefinierte Controller-Problem bei diesem versehentlichen Fehler auftreten, nicht einmal auf den Controller zu verweisen!

Tom Stickel
quelle
0

Dieser Fehler kann auch auftreten, wenn Sie ein großes Projekt mit vielen Modulen haben. Stellen Sie sicher, dass die in Ihrer Winkeldatei verwendete App (Modul) mit der in Ihrer Vorlage verwendeten übereinstimmt , in diesem Beispiel " 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
quelle
0

Wenn alles andere fehlschlägt und Sie Gulp oder ähnliches verwenden, führen Sie es einfach erneut aus!

Ich habe 30 Minuten vervierfacht, um alles zu überprüfen, wenn alles, was es brauchte, ein schneller Tritt in die Hose war.

sigmapi13
quelle
0

Wenn Sie Routen verwenden (hohe Wahrscheinlichkeit) und Ihre Konfiguration einen Verweis auf einen Controller in einem Modul enthält, der nicht als Abhängigkeit deklariert ist, schlägt die Initialisierung möglicherweise ebenfalls fehl.

Angenommen, Sie haben ngRoute für Ihre App konfiguriert, z

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

Seien Sie vorsichtig in dem Block, der die Routen deklariert.

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

Deklarieren Sie secondModuleals eine Abhängigkeit nach ‚ngRoute‘ sollte das Problem beheben. Ich weiß, dass ich dieses Problem hatte.

H. Rabiee
quelle
0

Ich habe diesen Fehler erhalten, weil ich eine ältere Version von Angular verwendet habe, die nicht mit meinem Code kompatibel war.

Dean Sha
quelle
0

Diese Fehler traten in meinem Fall vor Syntaxfehlern bei list.find () auf. Die 'find'-Methode einer Liste wird von IE11 nicht erkannt und muss daher durch die Filter-Methode ersetzt werden, die sowohl für IE11 als auch für Chrome funktioniert. Siehe https://github.com/flrs/visavail/issues/19

HydTechie
quelle
0

Diesem Fehler ging in meinem Fall ein Syntaxfehler bei der Suchmethode einer Liste in IE11 voraus. So ersetzt Find-Methode durch Filter-Methode wie vorgeschlagen https://github.com/flrs/visavail/issues/19

dann über Controller nicht definierter Fehler behoben.

HydTechie
quelle
-3

Ich habe den gleichen Fehler erhalten, als ich einem alten Tutorial mit (nicht alt genug) AngularJS 1.4.3 gefolgt bin. Die mit Abstand einfachste Lösung besteht darin, die Quelle von angle.js aus zu bearbeiten

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

zu

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

Befolgen Sie einfach das Lernprogramm wie es ist, und die veralteten globalen Funktionen funktionieren nur als Controller.

MKaama
quelle
Das ist schlechte Praxis. Wie in der Antwort von PSL erwähnt, können Sie dies folgendermaßen tun:angular.module('app') .config(['$controllerProvider', function($controllerProvider) { $controllerProvider.allowGlobals(); }]);
gm2008
-1. Dies ist auch eine großartige Möglichkeit, um sicherzustellen, dass (a) Sie dies überschreiben, sobald Sie ein Upgrade durchführen, wodurch unnötige (und falsche) Berichte generiert werden, dass "ein Upgrade von 1.4.3 auf 1.4.4 meine Anwendung beschädigt hat!" und / oder (b) Sie aktualisieren Ihre App nicht, weil "es schwierig ist".
Phillip Copley