1. ขอบเขตคืออะไร?
ขอบเขต (http://code.angularjs.org/1.0.2/docs/api/ng.$rootscope.scope) เป็นวัตถุที่ชี้ไปที่โมเดลแอปพลิเคชัน นอกจากนี้ยังเป็นบริบทการดำเนินการของนิพจน์ (http://www.cnblogs.com/lclao/archive/2012/09/16/2687162.html) ขอบเขตถูกวางไว้ในลำดับชั้นของโครงสร้าง DOM คล้ายกับของแอปพลิเคชัน ขอบเขตสามารถตรวจสอบ (ดู, $ watch) การแสดงออกและเหตุการณ์การแพร่กระจาย
2. ลักษณะของขอบเขต
3. ขอบเขตเป็นแบบจำลองข้อมูล (ขอบเขตเป็นแบบจำลองข้อมูล)
ขอบเขตคือลิงก์ระหว่างแอปพลิเคชันคอนโทรลเลอร์และมุมมอง ในขั้นตอนของการเชื่อมโยงแม่แบบ (http://www.cnblogs.com/lclao/archive/2012/09/04/2669802.html) คำสั่ง (http://www.cnblogs.com/lclao/archive/archive/2012/09/09/09/09/09/09/09/09/09/09/ ขอบเขต $ watch อนุญาตให้ Directive ทราบการเปลี่ยนแปลงในแอตทริบิวต์ดังนั้น Directive จะแสดงค่าที่อัปเดตลงใน DOM
ทั้งคอนโทรลเลอร์และคำสั่งมีการอ้างอิงถึงขอบเขต แต่ไม่ต่อกัน การจัดเรียงนี้จะแยกคอนโทรลเลอร์ออกจากคำสั่งและ DOM นี่เป็นสถานที่สำคัญเพราะมันแยกคอนโทรลเลอร์ออกจากมุมมองปรับปรุงเรื่องราวการทดสอบของแอปพลิเคชันอย่างมาก
<! doctype html> <html lang = "zh-cn" ng-app> <head> <meta charset = "utf-8"> <title> data-model </title> <style type = "css"> .ng-cloak {แสดง: ไม่มี; } </style> </head> <body> <div ng-controller = "myController"> ชื่อของคุณ: <อินพุต type = "text" ng-model = "ชื่อผู้ใช้"/> <button ng-click = "Sayelo ()"> ยินดีต้อนรับ </button> <hr/> {} type = "text/javascript"> </script> <script type = "text/javascript"> function myController ($ scope) {$ scope.username = "My Little Dada"; $ scope.sayhello = function () {$ scope.greeting = "hello ~" + $ scope.username + "!"; - } </script> </body> </html>ในตัวอย่างข้างต้นเราสามารถสังเกตได้ว่า MyController กำหนดแอตทริบิวต์ชื่อผู้ใช้ในขอบเขตด้วย "Dada ตัวน้อยของฉัน" จากนั้นขอบเขตจะแจ้งการป้อนข้อมูลสำหรับการมอบหมายและเติมค่าชื่อผู้ใช้ล่วงหน้าลงในอินพุต สิ่งนี้แสดงให้เห็นว่าคอนโทรลเลอร์สามารถเขียนข้อมูลลงในขอบเขตได้อย่างไร
ในทำนองเดียวกันคอนโทรลเลอร์สามารถแนบพฤติกรรมเข้ากับขอบเขตเช่นเดียวกับวิธี Sayhello ที่ถูกกระตุ้นเมื่อผู้ใช้คลิกปุ่ม "ยินดีต้อนรับ" วิธี Sayhello สามารถอ่านแอตทริบิวต์ชื่อผู้ใช้หรือสร้างแอตทริบิวต์ทักทาย สิ่งนี้แสดงให้เห็นว่าเมื่อพวกเขาถูกผูกไว้กับการควบคุมอินพุต HTML คุณสมบัติในขอบเขตจะได้รับการปรับปรุงโดยอัตโนมัติ
การแสดง {{คำทักทาย}} เกี่ยวข้องกับสองจุดต่อไปนี้:
ขอบเขตการค้นหาด้วยโหนดแม่แบบ DOM ที่กำหนดนิพจน์ {{ทักทาย}} ในตัวอย่างนี้ขอบเขตนี้เหมือนกับขอบเขตที่ส่งผ่านไปยัง MyController (เราจะหารือเกี่ยวกับลำดับชั้นของขอบเขตในภายหลัง)
นิพจน์การทักทายได้รับการประเมินผ่านขอบเขตที่ดึงมาก่อนหน้านี้และผลลัพธ์จะถูกใช้เป็นค่าของข้อความที่แนบองค์ประกอบ DOM
เราสามารถคิดได้ว่าขอบเขตและคุณสมบัติของตัวเองสามารถใช้เป็นข้อมูลสำหรับมุมมองการแสดงผล ขอบเขตเป็นแหล่งที่มาของความจริงสำหรับทุกสิ่งที่เกี่ยวข้องกับทุกสิ่งที่เกี่ยวข้อง
จากมุมมองความสามารถในการทดสอบการแยกตัวควบคุมและมุมมองมีความยินดีเนื่องจากช่วยให้เราสามารถ (มุ่งเน้น) พฤติกรรมการทดสอบโดยไม่ต้องมีการรบกวนของรายละเอียดการแสดงผล
มัน ('ควรทักทาย', function () {var scopemock = {}; var cntl = mycontroller ใหม่ (scopemock); // ยืนยันว่าชื่อผู้ใช้นั้นเต็มไปด้วยความคาดหวัง (scopemock.username) .toequal ('โลก'); คาดหวัง (scopemock.greeting) .toequal ('สวัสดี Angular!');});4. ลำดับชั้นขอบเขต (ลำดับชั้นขอบเขต)
แอปพลิเคชั่นเชิงมุมแต่ละอันมีและขอบเขตรูทเดียวเท่านั้น แต่สามารถมีขอบเขตเด็กได้หลายขอบเขต
แอปพลิเคชันสามารถมีขอบเขตเด็กหลายแห่งเนื่องจากคำสั่งบางอย่างจะสร้างขอบเขตเด็กใหม่ (ดูเอกสารคำสั่งเพื่อดูว่าคำสั่งใดที่สามารถสร้างขอบเขตใหม่เช่น NG-Repeat) เมื่อขอบเขตใหม่ถูกสร้างขึ้นพวกเขาจะถูกเพิ่มเข้าไปในขอบเขตหลักเป็นขอบเขตเด็ก ด้วยวิธีนี้โครงสร้างต้นไม้ที่คล้ายกับ DOM ที่แนบมาถูกสร้างขึ้น
เมื่อ Angular ประเมิน {{username}} มันจะดูที่คุณสมบัติชื่อผู้ใช้ของขอบเขตที่เกี่ยวข้องกับองค์ประกอบปัจจุบันก่อน หากไม่พบคุณสมบัติที่สอดคล้องกันมันจะค้นหาขอบเขตของผู้ปกครองจนกว่าจะถึงขอบเขตรูท ใน JavaScript พฤติกรรมนี้เรียกว่า "การสืบทอดต้นแบบ" และขอบเขตเด็กมักจะสืบทอดมาจากพ่อแม่ของพวกเขา
ตัวอย่างนี้แสดงขอบเขต (มันคืออะไร) และการสืบทอดต้นแบบของคุณสมบัติในแอปพลิเคชัน
<! doctype html> <html lang = "zh-cn" ng-app> <head> <meta charset = "utf-8"> <title> scope-hierarchies </title> <style type = "text/css"> .ng-cloak {แสดง: ไม่มี; } .ng-scope {border: 1px ประสีแดง; } </style> </head> <body> <div ng-controller = "myController"> manager: {{Employee.name}} [{{แผนก}}] <br/> รายงาน: <ul> <li ng-repeat = "พนักงาน </ul> <hr/> {{ทักทาย}} </div> <สคริปต์ src = "../ angular-1.0.1.js" type = "text/javascript"> </script> <script type = "javascript"> ฟังก์ชั่น myController ($ scope) $ scope.employee = {ชื่อ: "My Little Dada", รายงาน: [{ชื่อ: "lclao"}, {ชื่อ: "who^o^"}]}; } </script> </body> </html>โปรดทราบว่า Angular จะวางคลาสขอบเขต NG โดยอัตโนมัติลงในองค์ประกอบที่ปฏิบัติตามขอบเขต <style> ถูกกำหนดไว้ในตัวอย่างด้านบนโดยเน้นช่วงของขอบเขตใหม่ผ่านเส้นประสีแดง เนื่องจาก repeater ประเมินการแสดงออก {{Exployee.Name}} ขอบเขตของเด็กจึงจำเป็น แต่ขึ้นอยู่กับขอบเขตการแสดงออกของการแสดงออกขอบเขตที่แตกต่างกันมีผลลัพธ์ที่แตกต่างกัน ในทำนองเดียวกันค่าของ {{แผนก}} ได้รับการสืบทอดมาจากต้นแบบในขอบเขตราก เฉพาะเมื่อมีมันจะมีการกำหนดแอตทริบิวต์ของแผนก
5. การดึงขอบเขตจาก DOM (ดึงขอบเขตจาก DOM)
ขอบเขตถูกแนบไปกับ DOM เป็นแอตทริบิวต์ข้อมูล $ ขอบเขตและสามารถใช้สำหรับการดึงข้อมูลเพื่อวัตถุประสงค์ในการดีบัก (เป็นไปไม่ได้ที่จะดึงขอบเขตด้วยวิธีนี้ในแอปพลิเคชัน) ตำแหน่งของขอบเขตรูทที่แนบมากับ DOM ถูกกำหนดโดยตำแหน่งของคำสั่ง NG-APP โดยปกติแล้ว NG-APP จะถูกวางไว้ในองค์ประกอบ <HTML> แต่ยังสามารถวางไว้ในองค์ประกอบอื่น ๆ เช่นเพียงบางส่วนของมุมมองจะต้องถูกควบคุมโดย Angular
ดูขอบเขตในดีบักเกอร์:
1. ในเบราว์เซอร์คลิกขวาองค์ประกอบที่คุณสนใจและเลือก "ดูองค์ประกอบ" เราจะเห็นได้ว่าดีบักเกอร์เบราว์เซอร์เน้นองค์ประกอบที่เราเลือก
2. ดีบักเกอร์ช่วยให้เราสามารถเข้าถึงองค์ประกอบที่เลือกในปัจจุบันผ่านตัวแปร $ 0 ในคอนโซล
3. หากคุณต้องการดูขอบเขตที่เกี่ยวข้องเราสามารถป้อน: Angular.Element ($ 0) .Scope () ในคอนโซล
6. การเผยแพร่ขอบเขตเหตุการณ์ (การแพร่กระจายเหตุการณ์ขอบเขต)
ขอบเขตสามารถเผยแพร่เหตุการณ์ในลักษณะที่คล้ายกับเหตุการณ์ DOM กิจกรรมสามารถออกอากาศ (http://code.angularjs.org/1.0.2/docs/api/ng.$rootscope.scope#$broadcast) ไปยังขอบเขตเด็กหรือปล่อย (http://code.angularjs.org/1.0.2/docs/api/api/api/api (ถ้าฟังขอบเขตปัจจุบันจะถูกดำเนินการด้วย)
<! doctype html> <html lang = "zh-cn" ng-app> <head> <meta charset = "utf-8"> <title> scope-event-propagation </title> <style type = "css"> .ng-cloak {display: ไม่มี; } </style> </head> <body> <div ng-controller = "myController"> จำนวนรูทจำนวน: {{count}} <ul> <li ng-repeat = "ฉันใน [1]" ng-controller = "myController"> <button ng-click = "$ emit ( ng-click = "$ broadcast ('myEvent')"> $ broadcast ("myEvent") </button> <br/> จำนวนขอบเขตกลาง: {{count}} <ul> <li ng-repeat = "รายการใน [1,2]" ng-controller = "myController" </ul> </div> <script src = "../ angular-1.0.1.js" type = "text/javascript"> </script> <script type = "text/javascript"> ฟังก์ชั่น myController ($ scope) {$ scope.count = 0; $ scope. $ on ("myEvent", function () {$ scope.count ++;}); } </script> </body> </html>7. วงจรชีวิตขอบเขต (วงจรชีวิตขอบเขต)
ในกระแสเหตุการณ์ปกติของเบราว์เซอร์เมื่อเบราว์เซอร์ได้รับเหตุการณ์มันจะเรียกใช้การโทรกลับ JavaScript ที่สอดคล้องกัน เมื่อฟังก์ชั่นการโทรกลับถูกเรียกใช้เบราว์เซอร์จะวาด DOM ใหม่และกลับสู่สถานะที่คุณรอกิจกรรมต่อไป
เมื่อเบราว์เซอร์เรียกรหัส JavaScript นอกสภาพแวดล้อมการดำเนินการเชิงมุมนั่นหมายความว่า Angular ไม่ทราบการเปลี่ยนแปลงของแบบจำลอง ในการจัดการการดัดแปลงแบบจำลองอย่างถูกต้องคำสั่งนี้จะต้องเข้าสู่สภาพแวดล้อมการดำเนินการเชิงมุมโดยการสร้างวิธีการ $ ใช้ เฉพาะเมื่อโมเดลเปลี่ยนแปลงในวิธีการใช้ $ จะถูกนับอย่างถูกต้องโดย Angular ตัวอย่างเช่นคำสั่งฟังสำหรับเหตุการณ์ DOM เช่น NG-click ซึ่งจะต้องประเมินนิพจน์ในวิธีการ $ ใช้
หลังจากประเมินนิพจน์วิธีการใช้ $ ใช้จะดำเนินการ $ Digest ในขั้นตอน $ digest ขอบเขตตรวจสอบนิพจน์ทั้งหมดที่ฟังโดย $ watch และเปรียบเทียบค่าปัจจุบันกับค่าเก่า การตรวจสอบสกปรกเป็นแบบอะซิงโครนัส ซึ่งหมายความว่าคำสั่งการมอบหมาย (ตัวอย่างเช่น $ scope.username = "Angular") จะไม่ทำให้เกิดการแจ้งเตือน $ ทันที แต่การแจ้งเตือนของ $ watch จะถูกชะลอไปถึงขั้นตอน $ Digest ความล่าช้านี้เป็นสิ่งจำเป็นเพราะมันรวมการอัปเดตหลายรุ่นไว้ในการแจ้งเตือน $ watch ซึ่งทำให้มั่นใจได้ว่าจะไม่มีการดำเนินการดู $ อื่น ๆ ในระหว่างกระบวนการแจ้งเตือน $ หาก A $ watch เปลี่ยนค่าของโมเดลมันจะบังคับให้เพิ่มรอบ $ digest
1) การสร้าง (สร้างขอบเขต)
ขอบเขตรูทถูกสร้างขึ้นโดย $ injector (http://code.angularjs.org/1.0.2/docs/api/auto.$injector) ระหว่างกระบวนการเริ่มต้นแอปพลิเคชัน ในระหว่างกระบวนการเชื่อมโยงเทมเพลตคำสั่งบางอย่างจะสร้างขอบเขตเด็กใหม่
2) การลงทะเบียนของผู้เฝ้าดู (ลงทะเบียนผู้เฝ้าดู)
ในระหว่างกระบวนการเชื่อมโยงแม่แบบ Directive ลงทะเบียน $ ดูในขอบเขต นาฬิกาเหล่านี้จะถูกใช้เป็นค่าของการเผยแพร่โมเดลไปยัง DOM
3) การกลายพันธุ์ของแบบจำลอง (การเปลี่ยนแปลงแบบจำลอง)
เพื่อให้ตรวจพบการเปลี่ยนแปลงได้อย่างถูกต้องเราจำเป็นต้องห่อมันไว้ในขอบเขต $ ใช้ (API เชิงมุมได้ทำสิ่งนี้โดยปริยายดังนั้นเมื่อทำงานแบบซิงโครนัสในคอนโทรลเลอร์หรืองานอะซิงโครนัสด้วย $ http หรือ $ timeout ไม่จำเป็นต้องใช้การโทรเพิ่มเติมอีก $)
4) การสังเกตการกลายพันธุ์ (การตรวจสอบเปลี่ยน)
ในตอนท้ายของ $ apple, Angular จะดำเนินการรอบ $ digest ในขอบเขตรูทซึ่งจะเผยแพร่ไปยังขอบเขตเด็กทั้งหมด ในรอบ $ Digest นิพจน์หรือฟังก์ชั่นทั้งหมดที่ลงทะเบียนกับ $ นาฬิกาจะถูกตรวจสอบเพื่อตรวจสอบว่าโมเดลมีการเปลี่ยนแปลงหรือไม่ หากการเปลี่ยนแปลงเกิดขึ้นผู้ฟัง $ Watch ที่สอดคล้องกันจะถูกเรียก
5) การทำลายขอบเขต (การทำลายขอบเขต)
เมื่อขอบเขตเด็กไม่จำเป็นอีกต่อไปมันเป็นความรับผิดชอบของผู้ผลิตขอบเขตเด็กที่จะทำลายพวกเขาผ่านขอบเขต $ ทำลาย () API สิ่งนี้จะหยุดการแพร่กระจายของการเรียก $ Digest ในขอบเขตเด็กเพื่อให้หน่วยความจำที่ใช้โดยโมเดลขอบเขตเด็กสามารถนำกลับมาใช้ใหม่ได้โดย GC (Garbage Collector)
1. ขอบเขตและคำสั่ง
ในระหว่างขั้นตอนการรวบรวมคอมไพเลอร์ขึ้นอยู่กับคำสั่งการจับคู่แม่แบบ DOM คำสั่งสามารถแบ่งออกเป็นสองประเภท:
การสังเกตคำสั่งเช่นนิพจน์ dobule-curly {{expression}}, ลงทะเบียนผู้ฟังโดยใช้วิธีการดู $ เมื่อใดก็ตามที่การเปลี่ยนแปลง (ค่า) เปลี่ยนแปลงคำสั่งดังกล่าวจะต้องได้รับแจ้งให้อัปเดตมุมมอง
ผู้ฟัง Directive เช่น NG-click ลงทะเบียนผู้ฟังลงใน DOM เมื่อผู้ฟังของ DOM ยิงออกคำสั่งจะดำเนินการนิพจน์ที่เกี่ยวข้องและอัปเดตมุมมองโดยใช้วิธีการใช้ $
เมื่อได้ยินเหตุการณ์ภายนอก (เช่นการกระทำของผู้ใช้ตัวจับเวลาหรือ XHR) จะต้องใช้นิพจน์ที่เกี่ยวข้องกับขอบเขตผ่านวิธีการใช้ $ ใช้เพื่อให้ผู้ฟังทุกคนสามารถอัปเดตได้อย่างถูกต้อง
2. คำสั่งที่สร้างขอบเขต
ในกรณีส่วนใหญ่คำสั่งและขอบเขตมีอิทธิพลร่วมกัน แต่ไม่มีการสร้างอินสแตนซ์ขอบเขตใหม่ อย่างไรก็ตามคำสั่งบางอย่าง (เช่น NG-Controller และ NG-Repeat) สร้างขอบเขตใหม่โดยต่อท้ายขอบเขตเด็กเข้ากับองค์ประกอบ DOM ที่เกี่ยวข้อง เราดูขอบเขตขององค์ประกอบ DOM ใด ๆ โดยใช้ Angular.Element (AdoMelement) .Scope ()
3. คอนโทรลเลอร์และขอบเขต
ในกรณีต่อไปนี้ขอบเขตและคอนโทรลเลอร์มีอิทธิพลต่อกัน:
4. ขอบเขตการพิจารณาประสิทธิภาพ $ (ขอบเขตการพิจารณาประสิทธิภาพการดู $)
ในเชิงมุมมันเป็นการดำเนินการทั่วไปในการตรวจสอบสกปรกบนขอบเขตเพื่อตรวจจับการเปลี่ยนแปลงในแอตทริบิวต์ ในการทำเช่นนี้ต้องการให้ฟังก์ชั่นการตรวจสอบสกปรกต้องมีประสิทธิภาพ ระวังว่าฟังก์ชั่นการตรวจสอบสกปรกไม่ได้ทำการเข้าถึง DOM ใด ๆ เนื่องจากการเข้าถึง DOM เป็นคำสั่งของขนาดช้ากว่าการเข้าถึงคุณสมบัติของวัตถุ JavaScript
ข้างต้นคือข้อมูลเกี่ยวกับขอบเขต AngularJS เราจะยังคงเพิ่มข้อมูลที่เกี่ยวข้องในอนาคต ขอบคุณสำหรับการสนับสนุนเว็บไซต์นี้!