Kontroler nie jest funkcją, został niezdefiniowany podczas definiowania kontrolerów globalnie

123

Piszę przykładową aplikację przy użyciu angularjs. Wystąpił błąd wymieniony poniżej w przeglądarce Chrome.

Błąd jest

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

Który renderuje się jako

Argument „ContactController” nie jest funkcją, został niezdefiniowany

Kod

<!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
źródło

Odpowiedzi:

172

W Angular 1.3+ nie możesz już używać globalnej deklaracji kontrolera w zakresie globalnym (bez jawnej rejestracji). Będziesz musiał zarejestrować kontroler przy użyciu module.controllerskładni.

Przykład:-

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

        };
    }]);

lub

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

Jest to przełomowa zmiana, ale można ją wyłączyć, aby używać globali za pomocąallowGlobals .

Przykład:-

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

Oto komentarz ze źródła Angular: -

  • sprawdzić czy kontroler o podanej nazwie jest zarejestrowany przez $controllerProvider
  • sprawdź, czy ocena ciągu w bieżącym zakresie zwraca konstruktora
  • if $ controllerProvider # allowGlobals, sprawdź obiekt window[constructor]globalny window(niezalecane)
 .....

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

Dodatkowe kontrole: -

  • Pamiętaj, aby umieścić nazwę aplikacji w ng-appdyrektywie także w kątowym elemencie głównym (np .: - html). Przykład: - ng-app = "myApp"

  • Jeśli wszystko jest w porządku, a problem nadal występuje, pamiętaj, aby upewnić się, że w skryptach znajduje się odpowiedni plik.

  • Nie zdefiniowałeś tego samego modułu dwa razy w różnych miejscach, co powoduje wyczyszczenie dowolnych podmiotów zdefiniowanych wcześniej na tym samym module, Przykład angular.module('app',[]).controller(..i ponownie w innym miejscu angular.module('app',[]).service(..(oczywiście z obydwoma skryptami) może spowodować, że wcześniej zarejestrowany kontroler na moduł appdo wyczyszczenia przy drugim odtworzeniu modułu.

PSL
źródło
Jak to sprawdzić zgodnie z sugestią? sprawdź, czy kontroler o podanej nazwie jest zarejestrowany przez $ controllerProvider
geckob
app.register.controller ('TheController', TheController); załatwił sprawę dla mnie.
morph85
33

Mam ten problem, ponieważ opakowałem plik definicji kontrolera w zamknięciu:

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

Ale zapomniałem faktycznie wywołać to zamknięcie, aby wykonać kod definicji i faktycznie powiedzieć Javascriptowi, że mój kontroler istnieje. Tj. Powyższe musi być:

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

Zwróć uwagę na () na końcu.

rogueleaderr
źródło
1
+1 Co ciekawe, czasami Visual Studio automatycznie usuwa wywołanie. Skopiowałem istniejący plik js zawierający ten kod; oryginał miał wywołanie, skopiowany plik nie.
papergodzilla
16

Jestem początkującym użytkownikiem Angulara i popełniłem podstawowy błąd polegający na nieuwzględnieniu nazwy aplikacji w kątowym elemencie głównym. Tak więc zmiana kodu z

<html data-ng-app> 

do

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

pracował dla mnie. @PSL, omówił to już w swojej odpowiedzi powyżej.

Prakash Tiwari
źródło
8

Wystąpił ten błąd, ponieważ nie rozumiem różnicy między angular.module('myApp', [])i angular.module('myApp').

To tworzy moduł „myapp” i nadpisuje istniejący moduł o nazwie „myApp”:

angular.module('myApp', [])

Spowoduje to pobranie istniejącego modułu „myApp”:

angular.module('myApp')

Nadpisałem swój moduł w innym pliku, używając pierwszego wywołania powyżej, które utworzyło inny moduł zamiast pobierania zgodnie z oczekiwaniami.

Więcej szczegółów tutaj: https://docs.angularjs.org/guide/module

Jake Stewart
źródło
1
W moim przypadku dodałem moduł, dodałem kontroler, ale zapomniałem dodać moduł na liście modułów do aplikacji. `angular.module (" app ", [HEREYOURMODULE] ...`
Thomas
3

Właśnie przeprowadziłem migrację do angular 1.3.3 i odkryłem, że gdybym miał wiele kontrolerów w różnych plikach, gdy aplikacja została zastąpiona i straciłem pierwsze zadeklarowane kontenery.

Nie wiem, czy to dobra praktyka, ale może być pomocna przy innej.

var app = app;
if(!app) {
    app = angular.module('web', ['ui.bootstrap']);
}
app.controller('SearchCtrl', SearchCtrl);
Franzi
źródło
2

Miałem ten problem, gdy przypadkowo ponownie zadeklarowałem myApp:

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

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

Po ponownym zadeklarowaniu Controller1przestaje działać i podnosi błąd OP.

Daniel Flippance
źródło
2

Naprawdę świetna rada, poza tym SAMA błąd MOŻE wystąpić po prostu przez pominięcie krytycznego skryptu zawartego na stronie głównej

przykład:

strona: index.html

   np-app="saleApp"

Brakujący

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

Kiedy Route zostanie poinformowany, jaki kontroler i widok ma obsługiwać:

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

Tak istotne, że niezdefiniowany problem z kontrolerem MOŻE wystąpić w przypadku tego przypadkowego błędu, polegającego na braku odniesienia do kontrolera!

Tom Stickel
źródło
0

Ten błąd może również wystąpić, gdy masz duży projekt z wieloma modułami. Upewnij się, że aplikacja (moduł) używana w pliku kątowym jest taka sama, jak w szablonie, w tym przykładzie „ 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
źródło
0

Jeśli wszystko inne zawiedzie i używasz Gulp lub czegoś podobnego ... po prostu uruchom go ponownie!

Zmarnowałem 30 minut czterokrotnie sprawdzając wszystko, kiedy wszystko czego potrzebowało to szybkie kopnięcie w spodnie.

sigmapi13
źródło
0

Jeśli używasz tras (wysokie prawdopodobieństwo), a Twoja konfiguracja zawiera odwołanie do kontrolera w module, który nie jest zadeklarowany jako zależność, inicjalizacja również może się nie powieść.

Zakładając na przykład, że skonfigurowałeś ngRoute dla swojej aplikacji, na przykład

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

Uważaj w bloku, który deklaruje trasy,

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

Zadeklarowanie secondModulejako zależności po wyrażeniu „ngRoute” powinno rozwiązać problem. Wiem, że miałem ten problem.

H.Rabiee
źródło
0

Otrzymałem ten błąd, ponieważ używałem starszej wersji angular, która nie była zgodna z moim kodem.

Dean Sha
źródło
0

Te błędy wystąpiły, w moim przypadku, poprzedzone błędami składniowymi w funkcji list.find (); metoda „find” listy nierozpoznawanej przez IE11, więc musi zostać zastąpiona metodą Filter, która działa zarówno dla IE11, jak i chrome. zobacz https://github.com/flrs/visavail/issues/19

HydTechie
źródło
0

Ten błąd, w moim przypadku, poprzedzony błędem składniowym w metodzie find listy w IE11. więc zastąpiono metodę wyszukiwania metodą filtru zgodnie z sugestią https://github.com/flrs/visavail/issues/19

to powyżej kontroler nie zdefiniowany błąd rozwiązany.

HydTechie
źródło
-3

Otrzymałem ten sam błąd podczas korzystania ze starego samouczka z (nie dość starym) AngularJS 1.4.3. Zdecydowanie najprostszym rozwiązaniem jest edycja źródła angular.js z

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

do

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

i po prostu postępuj zgodnie z samouczkiem w obecnej postaci, a przestarzałe funkcje globalne działają tylko jako kontrolery.

MKaama
źródło
To zła praktyka. Jak wspomniano w odpowiedzi PSL, możesz to zrobić w następujący sposób:angular.module('app') .config(['$controllerProvider', function($controllerProvider) { $controllerProvider.allowGlobals(); }]);
gm2008
-1. Jest to również świetny sposób na upewnienie się, że (a) nadpisujesz to zaraz po uaktualnieniu, co spowoduje wygenerowanie niepotrzebnych (i niepoprawnych) raportów, że „aktualizacja 1.4.3 do 1.4.4 zepsuła moją aplikację!” i / lub (b) nie aktualizujesz aplikacji, ponieważ „jest to trudne”.
Phillip Copley