控制器不是一个功能,未定义,同时全局定义控制器

时间:2014-08-04 04:35:50

标签: javascript angularjs angularjs-directive angularjs-scope

我正在使用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>

14 个答案:

答案 0 :(得分: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);

这是一个突破性的变化,但can be turned off to use globals by using 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 =&#34; myApp&#34;

  • 如果一切正常并且您仍然遇到问题,请务必确保脚本中包含正确的文件。

  • 您没有在不同位置两次定义相同的模块,导致先前在同一模块上定义的任何实体被清除,示例angular.module('app',[]).controller(..并再次在另一个地方angular.module('app',[]).service(..(当然包含两个脚本)可以导致模块app上先前注册的控制器通过第二次模块重新清除。

答案 1 :(得分:33)

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

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

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

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

注意最后的()

答案 2 :(得分:16)

我是Angular的初学者,我做了一个基本错误,即不在角度根元素中包含应用名称。所以,改变代码

<html data-ng-app> 

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

为我工作。 @PSL已经在上面的答案中涵盖了这一点。

答案 3 :(得分:8)

我遇到此错误,因为我不理解angular.module('myApp', [])angular.module('myApp')之间的区别。

创建模块'myApp'并覆盖名为'myApp'的任何现有模块:

angular.module('myApp', [])

检索现有模块'myApp':

angular.module('myApp')

我在另一个文件中覆盖了我的模块,使用上面的第一个调用创建了另一个模块而不是按照我的预期进行检索。

此处提供更多详细信息:https://docs.angularjs.org/guide/module

答案 4 :(得分:3)

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

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

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

答案 5 :(得分:2)

当我意外重新声明myApp时,我遇到了这个问题:

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

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

重新声明后,Controller1停止工作并引发OP错误。

答案 6 :(得分:1)

非常好的建议,除了 SAME 错误只能通过错过您的根页上的关键脚本包含而发生

示例:

page:index.html

   np-app="saleApp"

<强>缺少

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

当路由被告知要提供哪个控制器和视图时:

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

非常重要的是未定义的控制器问题CAN在偶然错误中发生,甚至没有引用控制器!

答案 7 :(得分: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>

答案 8 :(得分:0)

如果所有其他方法都失败了并且你正在使用Gulp或类似的东西......只需重新运行它!

我浪费了30分钟四倍检查所有需要的东西是裤子里的快速踢。

答案 9 :(得分:0)

如果你正在使用路由(概率很高)并且你的配置引用了一个未被声明为依赖的模块中的控制器,那么初始化也可能会失败。

假设您已为您的应用配置了ngRoute,例如

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

在声明路线的区块中要小心,

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

在&#39; ngRoute&#39;之后将secondModule声明为依赖项。应该解决这个问题。我知道我有这个问题。

答案 10 :(得分:0)

我收到此错误是因为我使用的是与我的代码不兼容的较旧版本的角色。

答案 11 :(得分:0)

在我的情况下,这些错误发生在list.find()函数的语法错误之前; IE11无法识别的列表的“查找”方法,因此必须替换为Filter方法,该方法对IE11和chrome均适用。 请参阅https://github.com/flrs/visavail/issues/19

答案 12 :(得分:0)

在我的情况下,此错误之前是IE11中list的find方法的语法错误。因此按照建议的https://github.com/flrs/visavail/issues/19

替换为查找方法

则上述控制器未定义错误已解决。

答案 13 :(得分:-3)

我在使用(不够老)AngularJS 1.4.3的旧教程时遇到了同样的错误。到目前为止,最简单的解决方案是从

编辑 angular.js
function $ControllerProvider() {
  var controllers = {},
      globals = false;

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

并按原样按照教程进行操作,不推荐使用的全局函数仅用作控制器。