คอนโทรลเลอร์ไม่ใช่ฟังก์ชั่นไม่ได้กำหนดขณะที่กำหนดคอนโทรลเลอร์ทั่วโลก


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

ซึ่งแสดงผลเป็น

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

มันคือการเปลี่ยนแปลงที่จะหมด แต่ก็สามารถปิดการใช้งาน Globals allowGlobalsโดยใช้

ตัวอย่าง:-

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

นี่คือความคิดเห็นจากแหล่งที่มาเชิงมุม: -

  • ตรวจสอบว่ามีการลงทะเบียนคอนโทรลเลอร์ที่มีชื่อหรือไม่ $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คำสั่งในองค์ประกอบรากเชิงมุมของคุณ (เช่น: - html) ด้วย ตัวอย่าง: - ng-app = "myApp"

  • หากทุกอย่างเรียบร้อยดีและคุณยังคงได้รับปัญหาอย่าลืมตรวจสอบให้แน่ใจว่าคุณมีไฟล์ที่ถูกต้องรวมอยู่ในสคริปต์

  • คุณไม่ได้กำหนดโมดูลเดียวกันสองครั้งในตำแหน่งที่ต่างกันซึ่งส่งผลให้เอนทิตีใด ๆ ที่กำหนดไว้ก่อนหน้านี้ในโมดูลเดียวกันถูกล้างออกตัวอย่างangular.module('app',[]).controller(..และอีกครั้งในที่อื่นangular.module('app',[]).service(..(โดยมีทั้งสคริปต์รวมอยู่ด้วยแน่นอน) อาจทำให้คอนโทรลเลอร์ที่ลงทะเบียนก่อนหน้านี้บน โมดูลappที่จะล้างออกด้วยส่วนที่สองของโมดูล


จะตรวจสอบตามที่แนะนำได้อย่างไร? ตรวจสอบว่ามีการลงทะเบียนคอนโทรลเลอร์ที่มีชื่อผ่าน $ controllerProvider
geckob

app.register.controller ('TheController', TheController); ทำเคล็ดลับให้ฉัน
morph85

33

ฉันพบปัญหานี้เนื่องจากฉันได้ห่อไฟล์นิยามคอนโทรลเลอร์ไว้ในการปิด:

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

แต่ฉันลืมที่จะเรียกใช้การปิดนั้นเพื่อรันโค้ดคำจำกัดความนั้นและบอก Javascript ว่ามีคอนโทรลเลอร์ของฉันอยู่จริง กล่าวคือข้างต้นจะต้อง:

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

สังเกต () ในตอนท้าย


1
+1 ที่น่าสนใจคือบางครั้งวิชวลสตูดิโอจะลบคำขอโดยอัตโนมัติ ฉันคัดลอกไฟล์ js ที่มีอยู่ซึ่งมีรหัสนี้ ต้นฉบับมีการเรียกใช้ไฟล์ที่คัดลอกไม่ได้
papergodzilla

16

ฉันเป็นผู้เริ่มต้นใช้ 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

ฉันเพิ่งย้ายไปที่เชิงมุม 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

คำแนะนำที่ดีจริงๆยกเว้นว่าข้อผิดพลาด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

ฉันได้รับข้อผิดพลาดนี้เนื่องจากฉันใช้เชิงมุมรุ่นเก่าที่ไม่สามารถใช้งานร่วมกับรหัสของฉันได้


0

ข้อผิดพลาดเหล่านี้เกิดขึ้นในกรณีของฉันก่อนหน้าด้วยข้อผิดพลาดทางไวยากรณ์ที่ list.find () fuction; เมธอด 'find' ของรายการที่ IE11 ไม่รู้จักจึงต้องแทนที่ด้วยวิธีการกรองซึ่งใช้ได้กับทั้ง 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 ทำให้แอปพลิเคชันของฉันเสียหาย!" และ / หรือ (ข) คุณไม่อัปเกรดแอปของคุณเพราะ "มันยาก"
Phillip Copley
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.