javascript - Controller är inte en funktion, fick undefined, medan definiering av controllers globalt


Jag skriver en exempelapplikation med AngularJS. Jag fick ett fel som nämns nedan i Chrome-webbläsaren.

Felet är

Fel: [ng:areq] http://errors.angularjs.org/1.3.0-beta.17/ng/areq?p0=ContactController&p1=inte%20en%20funktion%2C%20fick%20undefined

Vilket återger som

Argumentet 'ContactController' är inte en funktion, fick undefined

Kod

<!DOCTYPE html>
<html ng-app>
<head>
    <script src="../angular.min.js"></script>
    <script type="text/javascript">
        function ContactController($scope) {
            $scope.contacts = ["[email ", "[email "];

            $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>

Svar #1

Med Angular 1.3+ kan du inte längre använda global controller-deklaration på den globala scopen (utan uttrycklig registrering). Du behöver registrera controllern med module.controller-syntaxen.

Exempel:-

angular.module('app', [])
    .controller('ContactController', ['$scope', function ContactController($scope) {
        $scope.contacts = ["[email ", "[email "];

        $scope.add = function() {
            $scope.contacts.push($scope.newcontact);
            $scope.newcontact = "";

        };
    }]);

eller

function ContactController($scope) {
    $scope.contacts = ["[email ", "[email "];

    $scope.add = function() {
        $scope.contacts.push($scope.newcontact);
        $scope.newcontact = "";
    };
}
ContactController.$inject = ['$scope'];
angular.module('app', []).controller('ContactController', ContactController);

Det är en brytande förändring men den kan stängas av för att använda globala genom att använda allowGlobals.

Exempel:-

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

Här är kommentaren från Angular-källan:-

  • kontrollera om en kontroller med det angivna namnet är registrerad via $controllerProvider
  • kontrollera om utvärdering av strängen i den aktuella scope:en returnerar en konstruktor
  • om $controllerProvider#allowGlobals, kontrollera window[constructor] på det globala window-objektet (rekommenderas inte)
 .....

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

Några ytterligare kontroller:-

  • Se till att också sätta appnamnet i ng-app-direktivet på ditt angular-root-element (t.ex. html). Exempel: ng-app="myApp"

  • Om allt är bra och du fortfarande får problemet, kom ihåg att se till att du har den rätta filen inkluderad i skripten.

  • Du har inte definierat samma modul två gånger på olika ställen, vilket resulterar i att alla entiteter som tidigare definierats på samma modul raderas. Exempel angular.module('app',[]).controller(.. och igen på ett annat ställe angular.module('app',[]).service(.. (med båda skripten inkluderade naturligtvis) kan göra att den tidigare registrerade controllern på modulen app raderas vid den andra återskapningen av modulen.

Svar #2

Jag fick detta problem eftersom jag hade omslutit en controller-definition fil i en closure:

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

Men jag hade glömt att faktiskt anropa den stängning för att köra den definitionskoden och faktiskt tala om för Javascript att min kontrollant existerade. Det vill säga, ovanstående behöver vara:

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

Notera() i slutet.

Svar #3

Jag är nybörjare på Angular och jag gjorde det grundläggande misstaget att inte inkludera appnamnet i Angulars rotelelement. Så, genom att ändra koden från

<html data-ng-app> 

att

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

funkade för mig. @PSL har redan täckt detta i sitt svar ovan.

Relaterade artiklar