Контроллер не является функцией, получил неопределенное значение при глобальном определении контроллеров


123

Я пишу образец приложения с использованием angularjs. У меня в браузере Chrome возникла ошибка, указанная ниже.

Ошибка

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

Что отображается как

Аргумент ContactController не является функцией, он не определен

Код

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

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

Ответы:


172

С Angular 1.3+ вы больше не можете использовать объявление глобального контроллера в глобальной области (без явной регистрации). Вам нужно будет зарегистрировать контроллер, используя module.controllerсинтаксис.

Пример:-

angular.module('app', [])
    .controller('ContactController', ['$scope', function ContactController($scope) {
        $scope.contacts = ["abcd@gmail.com", "abcd@yahoo.co.in"];

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

        };
    }]);

или

function ContactController($scope) {
    $scope.contacts = ["abcd@gmail.com", "abcd@yahoo.co.in"];

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

Это критическое изменение, но его можно отключить для использования глобальных переменных с помощьюallowGlobals .

Пример:-

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

Вот комментарий из источника Angular: -

  • проверьте, зарегистрирован ли контроллер с данным именем через $controllerProvider
  • проверьте, возвращает ли оценка строки в текущей области конструктор
  • if $ controllerProvider # allowGlobals, проверять window[constructor]глобальный windowобъект (не рекомендуется)
 .....

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

Некоторые дополнительные проверки: -

  • Обязательно укажите имя приложения в ng-appдирективе корневого элемента angular (например: - html). Пример: - ng-app = "myApp"

  • Если все в порядке, но проблема по-прежнему возникает, не забудьте убедиться, что в сценарии включен правильный файл.

  • Вы не определили один и тот же модуль дважды в разных местах, в результате чего любые объекты, определенные ранее в одном и том же модуле, должны быть очищены. Пример angular.module('app',[]).controller(..и снова в другом месте angular.module('app',[]).service(..(конечно, с обоими сценариями) может привести к тому, что ранее зарегистрированный контроллер на модуль appбудет очищен при втором воссоздании модуля.


Как это проверить, как предлагается? проверьте, зарегистрирован ли контроллер с данным именем через $ controllerProvider
geckob

app.register.controller ('Контроллер', Контроллер); сделал трюк для меня.
morph85

33

У меня возникла эта проблема, потому что я заключил файл определения контроллера в закрытие:

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

Но я забыл на самом деле вызвать это закрытие для выполнения этого кода определения и фактического сообщения Javascript о существовании моего контроллера. Т.е. выше должно быть:

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

Обратите внимание на () в конце.


1
+1 Интересно, что визуальная студия иногда автоматически убирает вызов. Я скопировал существующий файл js, содержащий этот код; оригинал имел вызов, а скопированный файл - нет.
papergodzilla

16

Я новичок в Angular, и я сделал основную ошибку, не включив имя приложения в корневой элемент angular. Итак, изменив код с

<html data-ng-app> 

в

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

работал у меня. @PSL уже рассказал об этом в своем ответе выше.


8

У меня была эта ошибка, потому что я не понимал разницы между angular.module('myApp', [])и angular.module('myApp').

Это создает модуль myApp и перезаписывает любой существующий модуль с именем myApp:

angular.module('myApp', [])

Это извлекает существующий модуль myApp:

angular.module('myApp')

Я перезаписывал свой модуль в другом файле, используя первый вызов выше, который создал другой модуль вместо того, чтобы получить, как я ожидал.

Подробнее здесь: https://docs.angularjs.org/guide/module


1
В моем случае я добавил модуль, я добавил контроллер, но я забыл добавить модуль в список модулей для приложения. `angular.module (" app ", [HEREYOURMODULE] ...`
Thomas

3

Я просто перехожу на angular 1.3.3 и обнаружил, что если бы у меня было несколько контроллеров в разных файлах, когда приложение было переопределено, и я потерял первые объявленные контейнеры.

Я не знаю, хорошая ли это практика, но, может быть, она пригодится для другого.

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

2

У меня возникла эта проблема, когда я случайно повторно объявил myApp:

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

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

После переобъявления Controller1перестает работать и выдает ошибку OP.


2

Действительно отличный совет, за исключением того, что ТАКАЯ ошибка МОЖЕТ возникнуть просто из-за отсутствия критического сценария, включенного на вашей корневой странице.

пример:

страница: index.html

   np-app="saleApp"

Отсутствует

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

Когда Маршруту сообщается, какой контроллер и представление обслужить:

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

Столь существенная проблема с неопределенным контроллером МОЖЕТ возникнуть из-за этой случайной ошибки, связанной с отсутствием ссылки на контроллер!


0

Эта ошибка также может возникнуть, если у вас большой проект с большим количеством модулей. Убедитесь, что приложение (модуль), используемое в вашем файле angular, совпадает с тем, что вы используете в своем шаблоне, в этом примере это « thisApp ».

app.js

angular
.module('thisApp', [])
    .controller('ContactController', ['$scope', function ContactController($scope) {
        $scope.contacts = ["abcd@gmail.com", "abcd@yahoo.co.in"];

        $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

Если ничего не помогает и вы используете Gulp или что-то подобное ... просто запустите его повторно!

Я потратил 30 минут на четырехкратную проверку всего, когда все, что требовалось, - это быстрый удар в штаны.


0

Если вы используете маршруты (высокая вероятность) и ваша конфигурация имеет ссылку на контроллер в модуле, который не объявлен как зависимость, то инициализация также может завершиться ошибкой.

Например, если вы настроили ngRoute для своего приложения, например

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

Будьте осторожны в блоке, который объявляет маршруты,

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

Объявление secondModuleкак зависимость после ngRoute должно решить проблему. Я знаю, что у меня была эта проблема.


0

Я получал эту ошибку, потому что использовал старую версию angular, несовместимую с моим кодом.


0

В моем случае эти ошибки возникли, им предшествовали синтаксические ошибки в функции list.find (); 'find' для списка, не распознаваемого IE11, поэтому его необходимо заменить методом Filter, который работает как для IE11, так и для Chrome. обратитесь https://github.com/flrs/visavail/issues/19


0

Этой ошибке в моем случае предшествовала синтаксическая ошибка метода поиска списка в IE11. поэтому заменил метод поиска методом фильтрации, как предлагается https://github.com/flrs/visavail/issues/19

то ошибка выше контроллера не определена.


-3

Я получил ту же ошибку, следуя старому руководству с (недостаточно старым) AngularJS 1.4.3. Безусловно, самое простое решение - отредактировать исходный код angular.js из

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

в

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

и просто следуйте руководству как есть, а устаревшие глобальные функции работают просто как контроллеры.


Это плохая практика. Как упоминалось в ответе PSL, вы можете сделать это следующим образом:angular.module('app') .config(['$controllerProvider', function($controllerProvider) { $controllerProvider.allowGlobals(); }]);
gm2008

-1. Это также отличный способ гарантировать, что (а) вы перезапишете это сразу после обновления, что приведет к появлению ненужных (и неверных) отчетов о том, что «обновление с 1.4.3 до 1.4.4 сломало мое приложение!» и / или (б) вы не обновляете свое приложение, потому что «это сложно».
Филлип Копли
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.