ใน Angular คอนโทรลเลอร์เป็นฟังก์ชัน JavaScript (ประเภท/คลาส) ที่ใช้เป็นอินสแตนซ์ของขอบเขตเชิงมุม (//www.vevb.com/article/91749.htm) ที่ขยายออกไปยกเว้นขอบเขตรูท เมื่อเราสร้างขอบเขตเด็กใหม่ผ่านขอบเขต $ ใหม่ API (http://docs.angularjs.org/api/ng.$rootscope.scope#$new) มีตัวเลือกที่จะส่งผ่านตัวควบคุมเป็นพารามิเตอร์ของวิธีการที่มีความผูกพัน (ฉันไม่เข้าใจที่นี่ สิ่งนี้จะบอก Angular ว่าต้องรวมคอนโทรลเลอร์และขอบเขตใหม่และขยายพฤติกรรม
คอนโทรลเลอร์สามารถใช้เป็น:
1. ตั้งค่าสถานะเริ่มต้นของวัตถุขอบเขต
2. เพิ่มพฤติกรรมในขอบเขต
1. การตั้งค่าสถานะเริ่มต้นของวัตถุขอบเขต
โดยปกติเมื่อเราสร้างแอปพลิเคชันเราต้องตั้งค่าสถานะการเริ่มต้นสำหรับขอบเขตเชิงมุม
Angular ใช้วัตถุขอบเขตใหม่กับตัวสร้างคอนโทรลเลอร์ (คาดว่าจะถูกส่งผ่านเป็นพารามิเตอร์) และกำหนดสถานะขอบเขตเริ่มต้น ซึ่งหมายความว่า Angular ไม่เคยสร้างอินสแตนซ์ประเภทคอนโทรลเลอร์ (เช่นไม่ใช้ตัวดำเนินการใหม่สำหรับตัวสร้างคอนโทรลเลอร์) ตัวสร้างจะถูกนำไปใช้กับวัตถุขอบเขตที่มีอยู่เสมอ
เราสร้างสถานะเริ่มต้นของขอบเขตโดยการสร้างแอตทริบิวต์โมเดล ตัวอย่างเช่น:
Function GreetingCtrl ($ scope) {$ scope.greeting = "hola!";}
คอนโทรลเลอร์ "GreetingCtrl" สร้างแบบจำลองที่เรียกว่า "คำทักทาย" ที่สามารถนำไปใช้กับเทมเพลตได้
2. การเพิ่มพฤติกรรมลงในวัตถุขอบเขต
พฤติกรรมของวัตถุขอบเขตเชิงมุมอยู่ในรูปแบบของคุณลักษณะวิธีการขอบเขตสำหรับเทมเพลตและมุมมอง พฤติกรรมนี้สามารถปรับเปลี่ยนโมเดลของแอปพลิเคชัน
ตามที่กล่าวไว้ในบทที่นำทาง (//www.vevb.com/article/91777.htm) วัตถุใด ๆ (หรือประเภทดั้งเดิม) จะถูกกำหนดให้กับขอบเขตและกลายเป็นแอตทริบิวต์ของแบบจำลอง ฟังก์ชั่นใด ๆ ที่แนบมากับขอบเขตมีให้สำหรับมุมมองเทมเพลตและสามารถเรียกผ่านการแสดงออกเชิงมุมหรือผ่าน NG Event Handler Directive (เช่น NGCLICK)
3. การใช้คอนโทรลเลอร์อย่างถูกต้อง
โดยทั่วไปแล้วผู้ควบคุมไม่ควรพยายามทำมากเกินไป มันควรมีเพียงตรรกะทางธุรกิจที่จำเป็นสำหรับมุมมองเดียว (และมันไม่ได้หันไปรอบ ๆ และฉันมักจะคิดว่าคอนโทรลเลอร์เป็นเพียงการส่งต่อ ... )
เพื่อให้คอนโทรลเลอร์ง่ายวิธีทั่วไปคือการแยกงานที่ไม่ได้เป็นของคอนโทรลเลอร์ลงในบริการและใช้บริการเหล่านี้ผ่านการฉีดพึ่งพาในคอนโทรลเลอร์ สิ่งเหล่านี้จะถูกกล่าวถึงในบทบริการฉีดพึ่งพาของพ่อมด
อย่าทำสิ่งต่อไปนี้ในคอนโทรลเลอร์:
4. การเชื่อมโยงคอนโทรลเลอร์กับวัตถุขอบเขตเชิงมุม
เราสามารถเชื่อมโยงคอนโทรลเลอร์และขอบเขตวัตถุผ่านขอบเขตได้อย่างชัดเจน $ ใหม่หรือใช้ NgController Directive (http://docs.angularjs.org/api/ng.directive:ngcontroller) หรือ $ Service (http://docs.angularjs.org/api
1. ตัวอย่างของตัวสร้างคอนโทรลเลอร์และวิธีการ
เพื่อแสดงให้เห็นว่าส่วนประกอบคอนโทรลเลอร์ทำงานเป็นเชิงมุมอย่างไรให้สร้างแอปพลิเคชันขนาดเล็กโดยใช้ส่วนประกอบต่อไปนี้:
ข้อความในเทมเพลตของเรามีการเชื่อมโยงกับโมเดลเครื่องเทศซึ่งตั้งค่าเป็น "มาก" โดยค่าเริ่มต้น ตั้งค่าโมเดลเครื่องเทศเป็น "พริก" หรือ "Jalapeño" ตามปุ่มที่ถูกคลิกและข้อความจะได้รับการปรับปรุงโดยอัตโนมัติโดยการเชื่อมโยงข้อมูล
<! doctype html> <html ng-app> <head> <meta http-equiv = "content-type" content = "text/html; charset = utf-8"/> <title> spicy-controller </title> type = "text/css"> .ng-cloak {display: none; } </style> </head> <body> <div ng-controller = "spicyctrl"> <button ng-click = "chilispicy ()"> chili </button> <button ng-click = "jalapenospicy ('jalapeño')"> Jalape <script src = "../ angular-1.0.1.js" type = "text/javascript"> </script> <script type = "text/javascript"> function spicyctrl ($ scope) {$ scope.spice = "มาก"; $ scope.chilispicy = function () {$ spope.spice = "Chili"; - $ scope.jalapenospicy = function (val) {this.spice = val; - } </script> </body> </html>สิ่งที่ควรทราบในตัวอย่างข้างต้น:
วิธีคอนโทรลเลอร์สามารถใช้พารามิเตอร์ดังที่แสดงในตัวอย่างต่อไปนี้:
<! doctype html> <html ng-app> <head> <meta http-equiv = "content-type" content = "text/html; charset = utf-8"/> <title> controller-method-erments </title> type = "text/css"> .ng-cloak {display: none; } </style> </head> <body> <div ng-controller = "spicyctrl"> <อินพุต ng-model = "customspice" value = "wasabi"/> <button ng-click = "spicy (customspice)"> customs </button> <br/> {{Spice}} Spicy! </p> </div> <script src = "../ angular-1.0.1.js" type = "text/javascript"> </script> <script type = "text/javascript"> function spicyctrl ($ scope) $ scope.spicy = function (Spice) {$ scope.spice = Spice; - } </script> </body> </html>โปรดทราบว่าตอนนี้คอนโทรลเลอร์ Spicyctrl จะกำหนดวิธีการด้วยพารามิเตอร์ "เครื่องเทศ" และเรียกว่า "เผ็ด" เทมเพลตสามารถอ้างถึงวิธีการควบคุมและส่งผ่านสตริงคงที่หรือค่าโมเดลไป
มรดกของคอนโทรลเลอร์ใน Angular ขึ้นอยู่กับการสืบทอดขอบเขต ลองดูตัวอย่างต่อไปนี้:
<! doctype html> <html ng-app> <head> <meta http-equiv = "content-type" content = "text/html; charset = utf-8"/> <title> controlleritance </title> type = "text/css"> .ng-cloak {display: none; } </style> </head> <body> <div ng-controller = "mainctrl"> <p> ดี {{timeofday}}, {{name}}! ng-controller = "babyctrl"> good {{timeofday}}, {{name}}! </p> </div> </div> <script src = "../ angular-1.0.1.js" type = "text/javascript"> </script> 'เวลาหลัก'; $ scope.name = 'ชื่อหลัก'; } ฟังก์ชั่น childctrl ($ scope) {$ scope.name = 'ชื่อลูก'; } function babyctrl ($ scope) {$ scope.timeofday = 'Baby Time'; $ scope.name = 'ชื่อทารก'; } </script> </body> </html>สังเกตว่าเราทำรัง 3 ngcontroller ลงในเทมเพลตได้อย่างไร สำหรับมุมมองของเราโครงสร้างเทมเพลตนี้จะทำให้ 4 ขอบเขตที่จะสร้าง:
งานที่สืบทอดมานั้นเหมือนกันในคอนโทรลเลอร์และโมเดล ดังนั้นในตัวอย่างก่อนหน้าของเราทุกรุ่นสามารถเขียนใหม่ผ่านคอนโทรลเลอร์
หมายเหตุ: การสืบทอดต้นแบบมาตรฐานระหว่างตัวควบคุมสองตัวไม่ทำงานอย่างที่เราคิดเพราะอย่างที่เรากล่าวถึงก่อนหน้านี้คอนโทรลเลอร์ไม่ได้เริ่มต้นโดยตรงผ่านเชิงมุม แต่ใช้วัตถุขอบเขตนั้นแทน (คอนโทรลเลอร์ไม่ได้สร้างอินสแตนซ์โดยตรงโดย Angular แต่จะถูกนำไปใช้กับวัตถุขอบเขตที่นี่เหมือนเดิมฉันยังไม่เข้าใจ)
5. ตัวควบคุมการทดสอบ
ในขณะที่มีหลายวิธีในการทดสอบคอนโทรลเลอร์หนึ่งในอนุสัญญาที่ดีที่สุดดังที่แสดงด้านล่างต้องใช้การฉีด $ rootscope และ $ controller (การทดสอบจะต้องมีการประสานงานกับ jasmine.js)
<! doctype html> <html ng-app> <head> <meta http-equiv = "content-type" content = "text/html; charset = utf-8"/> <title> controller-test </title> href = "../ jasmine.css"> <style type = "text/css"> .ng-cloak {display: none; } </style> </head> <body> <script src = "../ angular-1.0.1.js" type = "text/javascript"> </script> <script src = "../ angular-scenario-1.0.1.js" type = "javascript" type = "text/javascript"> </script> <script src = "../ angular-mocks-1.0.1.js" type = "text/javascript"> </script> <script type = "text/javaScript"> function mycontroller ($ scope) {"ชื่อ": "Jalapeno", "Spiceiness": "ร้อนแรงร้อนแรง!"}, {"ชื่อ": "Habanero", "Spiceness": "Lava Hot !!"}]; $ scope.spice = "Habanero"; } อธิบาย ("MyController function", function () {อธิบาย ("myController", function () {var scope; ก่อนหน้า (inject (ฟังก์ชั่น ($ rootscope, $ controller) {scope = $ rootscope. $ new (); Spices ', function () {คาดหวัง (scope.spices.length) .tobe (3);}); - (ฟังก์ชั่น () {var jasmineenv = jasmine.getenv (); jasmineenv.updateInterval = 1000; var trivialreporter = jasmine.trivialreporter () jasmineenv.addreporter var currentwindowonload = window.onload;หากเราต้องการทดสอบคอนโทรลเลอร์ที่ซ้อนกันเราจำเป็นต้องสร้างความสัมพันธ์ในการสืบทอดขอบเขตเดียวกันในการทดสอบเช่นเดียวกับใน DOM
<! doctype html> <html ng-app> <head> <meta http-equiv = "content-type" content = "text/html; charset = utf-8"/> <title> controller-test </title> href = "../ jasmine.css"> <style type = "text/css"> .ng-cloak {display: none; } </style> </head> <body> <script src = "../ angular-1.0.1.js" type = "text/javascript"> </script> <script src = "../ angular-scenario-1.0.1.js" type = "javascript" type = "text/javascript"> </script> <script src = "../ angular-mocks-1.0.1.js" type = "text/javascript"> </script> <script type = "text/javascript"> ฟังก์ชั่น mainctrl ($ scope) {$ scope.timeofday = $ scope.name = 'ชื่อหลัก'; } ฟังก์ชั่น childctrl ($ scope) {$ scope.name = 'ชื่อลูก'; } function babyctrl ($ scope) {$ scope.timeofday = 'Baby Time'; $ scope.name = 'ชื่อทารก'; } อธิบาย ("myController", function () {var mainscope, childscope, babyscope; ก่อนหน้า (inject (ฟังก์ชั่น ($ rootscope, $ controller) {mainscope = $ rootscope. $ new (); var mainctrl = $ controller $ controller (childctrl, {$ scope: childscope}); คาดหวังว่า (Mainscope.name). Tobe ("ชื่อหลัก"); (ฟังก์ชั่น () {var jasmineenv = jasmine.getenv (); jasmineenv.updateInterval = 1000; var trivialreporter = jasmine.trivialreporter () jasmineenv.addreporter var currentwindowonload = window.onload;ข้างต้นคือข้อมูลเกี่ยวกับ AngularJS ทำความเข้าใจกับองค์ประกอบคอนโทรลเลอร์ เราจะยังคงเพิ่มข้อมูลที่เกี่ยวข้องในอนาคต ขอบคุณสำหรับการสนับสนุน!