控制器不是函数,未定义,但在全局定义控制器时


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>

Answers:


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
  • 检查在当前作用域上评估字符串是否返回构造函数
  • 如果$ controllerProvider#allowGlobals,检查window[constructor]全局window对象(不推荐)
 .....

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

其他一些检查:

  • 一定要确保将appname放在ng-app指令中,也要放在您的角根元素(例如:-)上html。例如:-ng-app =“ myApp”

  • 如果一切正常,但仍然遇到问题,请记住确保脚本中包含正确的文件。

  • 您没有在不同的位置定义两次相同的模块,这导致先前在同一模块上定义的任何实体都将被清除,例如angular.module('app',[]).controller(..,在另一个位置angular.module('app',[]).service(..(示例同时包含两个脚本)在另一个示例中会导致先前注册的控制器在模块app的第二次重新创建将清除该模块。


如何按照建议检查?检查是否通过$ controllerProvider注册了具有给定名称的控制器
geckob

app.register.controller('TheController',TheController); 为我做了把戏。
morph85 2015年

33

我遇到了这个问题,因为我将控制器定义文件包装在了一个闭包中:

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

但是我忘记了实际上调用该闭包来执行该定义代码,并实际上告诉Javascript我的控制器存在。即,上述内容必须为:

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

注意最后的()。


1
+1有趣的是,似乎Visual Studio有时会自动删除该调用。我复制了一个包含此代码的现有js文件;原始文件有调用,复制的文件没有。
papergodzilla

16

我是Angular的初学者,但我犯了一个基本错误,即没有将应用程序名称包含在angular root元素中。因此,从

<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] ...`
托马斯

3

我只是迁移到angular 1.3.3,我发现如果当app被覆盖并且我丢失了第一个声明的容器时,我在不同文件中有多个控制器。

我不知道这是否是一个好习惯,但也许对另一个人会有帮助。

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

确实是个好建议,但仅通过丢失根页面中包含的关键脚本就可以发生SAME错误

例:

页面:index.html

   np-app="saleApp"

失踪

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

当告知路线要使用的控制器和视图时:

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

因此,根本没有引用控制器的偶然错误就会发生未定义的控制器问题!


0

当您的大型项目包含许多模块时,也可能会发生此错误。确保在角度文件中使用的应用程序(模块)与模板中使用的应用程序(模块)相同,在本示例中为“ 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与我的代码不兼容。




-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 '16

-1。这也是确保(a)升级后立即覆盖它的好方法,这将生成不必要的(且不正确的)报告,即“将1.4.3升级到1.4.4破坏了我的应用程序!” 和/或(b)您不升级应用程序,因为“这很难”。
菲利普·科普利2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.