it-swarm.com.ru

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

Я пишу пример приложения, используя 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 = ["[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>
121
yokks

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

Пример:-

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

        };
    }]);

или же

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

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

Пример:-

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

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

  • проверить, зарегистрирован ли контроллер с данным именем через $controllerProvider
  • проверить, возвращает ли вычисление строки в текущей области видимость конструктор
  • если $ 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, который будет очищен со вторым пересозданием модуля.

172
PSL

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

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

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

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

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

33
rogueleaderr

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

<html data-ng-app> 

в

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

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

16
Prakash Tiwari

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

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

angular.module('myApp', [])

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

angular.module('myApp')

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

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

8
Jake Stewart

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

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

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

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

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

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

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

2
Daniel Flippance

Очень хороший совет, за исключением того, что ошибка SAME МОЖЕТ произойти, если просто пропустить критический скрипт, включенный в вашу корневую страницу.

пример:

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

   np-app="saleApp"

Missing

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

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

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

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

1
Tom Stickel

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

Я потратил 30 минут на проверку в четыре раза, когда все, что нужно, это Swift удар по штанам.

0
sigmapi13

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

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

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

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

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

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

0
H.Rabiee

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

0
HydTechie

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

0
Dean Sha

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

затем вышеуказанный контроллер не определен, ошибка устранена.

0
HydTechie

Эта ошибка также может возникать, когда у вас большой проект со многими модулями. Убедитесь, что приложение (модуль), использованное в вашем файле angular, совпадает с тем, которое вы используете в своем шаблоне, в этом примере "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>
0
Patrick