สำหรับฉันที่เป็นสามเณรที่บริสุทธิ์ในส่วนหน้า JavaScript ยังคงชัดเจนเล็กน้อยเกี่ยวกับเรื่องนี้ หากคุณต้องการเริ่มต้นกับ Angular JS โดยตรงมีการต่อต้านมากมาย แต่ฉันเชื่อว่าตราบใดที่คุณทำงานหนักแม้กระทั่งการออกแบบต่อต้านมนุษย์ก็จะไม่เป็นปัญหาใหญ่
โอเคอย่าพูดเรื่องไร้สาระมากนัก หากต้องการทราบว่า Angular JS คืออะไรฉันเริ่มต้นด้วยขอบเขต ขอบเขตคืออะไร? การยืมข้อความจากเอกสารอย่างเป็นทางการ:
การคัดลอกรหัสมีดังนี้:
“ ขอบเขตเป็นวัตถุที่อ้างถึงโมเดลแอปพลิเคชันมันเป็นบริบทการดำเนินการสำหรับการแสดงออกขอบเขตจะถูกจัดเรียงในโครงสร้างลำดับชั้นซึ่งเลียนแบบโครงสร้าง DOM ของแอปพลิเคชันขอบเขตสามารถดูการแสดงออกและการเผยแพร่เหตุการณ์”
หลังจากอ่านแล้วฉันเปรียบเทียบกับภาษาการเขียนโปรแกรมอื่น ๆ และรู้สึกว่าขอบเขตนั้นเป็นเหมือนขอบเขตของรูปแบบข้อมูลโดยให้บริบทสำหรับการดำเนินการนิพจน์ มาเข้าใจกันเถอะตอนนี้
คุณสมบัติของขอบเขต
ต่อไปมาดูกันว่าขอบเขตคุณสมบัติมีอะไรบ้าง
ขอบเขตมีวิธีการดู $ เพื่อตรวจสอบการเปลี่ยนแปลงในโมเดล
ขอบเขตมีวิธีการ $ ใช้เพื่อเผยแพร่การเปลี่ยนแปลงในรูปแบบ
ขอบเขตสามารถสืบทอดและแยกส่วนประกอบแอปพลิเคชันที่แตกต่างกันและสิทธิ์การเข้าถึงแอตทริบิวต์
ขอบเขตให้บริบทสำหรับการคำนวณการแสดงออก
สำหรับคุณสมบัติทั้งสี่นี้เพราะฉันได้เรียนรู้ Actionscript, C ++ และ Java มาก่อนมันไม่ยากที่จะเข้าใจคะแนนที่หนึ่งสามและสี่ แต่จุดที่สองรู้สึกสับสนเล็กน้อย ตามหลักการของการทำลายหม้อตุ๋นและถามถึงจุดจบฉันยังคงพบบางสิ่งผ่าน Google สำหรับทหารผ่านศึกที่มีประสบการณ์โปรดตบอิฐ!
ต้นกำเนิดของจาวาสคริปต์
ก่อนอื่นเมื่อมองแวบแรก Prope.apply () ดูเหมือนจะเป็นวิธีธรรมดาในการอัปเดตการเชื่อมโยง แต่คิดอีกหน่อยว่าทำไมเราถึงต้องการมัน? คุณมักจะใช้เมื่อไหร่? เพื่อให้เข้าใจถึงปัญหาทั้งสองนี้เราต้องเริ่มต้นด้วย JavaScript ในรหัส JavaScript พวกเขาจะดำเนินการตามลำดับที่แน่นอน เมื่อมันเป็นการเปลี่ยนตัวอย่างโค้ดที่จะดำเนินการเบราว์เซอร์จะเรียกใช้งานตัวอย่างปัจจุบันเท่านั้นและจะไม่ทำอย่างอื่น ดังนั้นบางครั้งเว็บเพจบางหน้าที่ไม่ได้ทำอย่างดีจะติดอยู่เมื่อคลิกที่บางสิ่งบางอย่าง JavaScript ทำงานหนึ่งในเหตุผลที่ทำให้เกิดปรากฏการณ์นี้! ที่นี่เรามีรหัสชิ้นหนึ่งที่จะได้สัมผัส:
การคัดลอกรหัสมีดังนี้:
ปุ่ม var = document.getElementById ('clickme');
ฟังก์ชั่น buttonclicked () {
การแจ้งเตือน ('คลิกปุ่ม');
-
button.addeventListener ('คลิก', buttonclicked);
ฟังก์ชัน TimerComplete () {
การแจ้งเตือน ('Timer Complete');
-
Settimeout (TimerComplete, 5000);
เมื่อโหลดรหัส JavaScript ก่อนอื่นให้ค้นหาปุ่มที่มี ID ที่เรียกว่า "ClickMe" จากนั้นเพิ่มฟังแล้วตั้งค่าการหมดเวลา รอ 5 วินาทีและกล่องโต้ตอบจะปรากฏขึ้น หากคุณรีเฟรชหน้าและคลิกปุ่ม ClickMe ทันทีกล่องโต้ตอบจะปรากฏขึ้น หากคุณไม่คลิกตกลงฟังก์ชั่น TimerComplete จะไม่มีโอกาสดำเนินการ
วิธีอัปเดตการผูก
โอเคหลังจากพูดถึงสิ่งที่ดูเหมือนไม่เกี่ยวข้องมากลับไปที่หัวข้อกันเถอะ Angular JS รู้ได้อย่างไรว่าต้องมีการปรับปรุงข้อมูลและหน้าเว็บอย่างไร รหัสจำเป็นต้องทราบเมื่อข้อมูลได้รับการแก้ไข แต่ตอนนี้ไม่มีวิธีที่จะแจ้งข้อมูลเกี่ยวกับวัตถุที่มีการเปลี่ยนแปลงโดยตรง (แม้ว่า ECMASCript 5 กำลังพยายามแก้ปัญหานี้ แต่ก็ยังอยู่ในขั้นตอนการทดลอง) ปัจจุบันมีวิธีแก้ปัญหาสองวิธีสำหรับกลยุทธ์หลักมากขึ้น หนึ่งคือการใช้วัตถุพิเศษเพื่อให้ข้อมูลทั้งหมดสามารถตั้งค่าได้โดยเรียกใช้วิธีวัตถุแทนที่จะระบุโดยตรงผ่านคุณสมบัติ ด้วยวิธีนี้การแก้ไขทั้งหมดสามารถบันทึกได้และคุณจะรู้ว่าจะต้องอัปเดตหน้าเว็บเมื่อใด ข้อเสียของการทำเช่นนี้คือเราต้องสืบทอดวัตถุพิเศษ สำหรับการมอบหมายสามารถทำได้โดย Object.set ('คีย์', 'ค่า') แทน object.key = value ในเฟรมเวิร์กนี่คือสิ่งที่ Emberjs และ Knockoutjs ทำ (แม้ว่าฉันจะไม่ได้สัมผัสมาก่อน) อีกวิธีหนึ่งคือวิธีการที่นำมาใช้โดย Angular JS ซึ่งตรวจสอบว่ามีการเปลี่ยนแปลงข้อมูลใด ๆ หลังจากดำเนินการตามลำดับการดำเนินการรหัส JavaScript แต่ละรายการหรือไม่ สิ่งนี้ดูเหมือนจะไม่ได้มีประสิทธิภาพและส่งผลกระทบอย่างจริงจังต่อประสิทธิภาพ อย่างไรก็ตาม Angular JS ใช้วิธีการที่ฉลาดในการแก้ปัญหานี้ (ยังไม่ได้ศึกษาและยังไม่ชัดเจน) ข้อได้เปรียบของการทำเช่นนี้คือเราสามารถใช้วัตถุใด ๆ ได้ตามต้องการไม่มีการ จำกัด วิธีการกำหนดและเรายังสามารถตระหนักถึงการเปลี่ยนแปลงข้อมูล
สำหรับโซลูชันนี้ที่นำมาใช้โดย Angular JS เราใส่ใจเมื่อข้อมูลเปลี่ยนไปและนั่นคือที่ที่ขอบเขต Apply () มีประโยชน์ การตรวจสอบว่าข้อมูลที่ถูกผูกมัดมีการเปลี่ยนแปลงจริง ๆ แล้วมันทำจริงโดยขอบเขต digest () แต่เราแทบจะไม่เคยเรียกวิธีนี้โดยตรง แต่แทนที่จะเรียกว่าเมธอด apply () เพราะในเมธอด apply () มันจะเรียกใช้เมธอด scope.digest () เมธอดขอบเขต () ใช้ฟังก์ชันหรือนิพจน์จากนั้นเรียกใช้งานและในที่สุดเรียกใช้เมธอด scope.digest () เพื่ออัปเดตการเชื่อมโยงหรือผู้เฝ้าดู
เมื่อใดควรใช้ $ apple ()
คำถามเดียวกันคือเมื่อใดที่เราต้องโทรหาวิธีการสมัคร () มีกรณีน้อยมาก ในความเป็นจริงรหัสเกือบทั้งหมดของเราถูกห่อหุ้มด้วยขอบเขต Apply () เช่น NG-click, การเริ่มต้นคอนโทรลเลอร์, ฟังก์ชั่นการโทรกลับ http ฯลฯ ในกรณีเหล่านี้เราไม่จำเป็นต้องโทรหาตัวเองและในความเป็นจริงเราไม่สามารถเรียกตัวเองได้ หากเราต้องการเรียกใช้รหัสในลำดับการดำเนินการใหม่เราจำเป็นต้องใช้มันและหากลำดับการดำเนินการใหม่ไม่ได้ถูกสร้างขึ้นโดยวิธีไลบรารี JS เชิงมุมเราจำเป็นต้องห่อรหัสในขอบเขต () นี่คือตัวอย่างที่จะอธิบาย:
การคัดลอกรหัสมีดังนี้:
<div ng: แอพ ng-controller = "ctrl"> {{message}} </div>
การคัดลอกรหัสมีดังนี้:
functionctrl ($ scope) {
$ scope.message = "รอ 2000ms สำหรับการอัปเดต";
settimeout (function () {
$ scope.message = "หมดเวลาเรียก!";
// Angularjs ไม่รู้การอัปเดตเป็น $ SCOPE
}, 2000);
-
หลังจากดำเนินการรหัสด้านบนหน้าจะแสดง: รอ 2,000 ม. สำหรับการอัปเดต เห็นได้ชัดว่าการอัปเดตข้อมูลไม่ได้รับการตรวจพบโดย Angular JS
ต่อไปเราจะปรับเปลี่ยนรหัส JavaScript เล็กน้อยและห่อด้วย prope.apply ()
การคัดลอกรหัสมีดังนี้:
functionctrl ($ scope) {
$ scope.message = "รอ 2000ms สำหรับการอัปเดต";
settimeout (function () {
$ scope. $ apple (function () {
$ scope.message = "หมดเวลาเรียก!";
-
}, 2000);
-
ความแตกต่างในเวลานี้คือหน้าจะแสดงเป็นครั้งแรก: รอ 2,000 มม. สำหรับการอัปเดต หลังจากรอ 2 วินาทีเนื้อหาจะถูกเปลี่ยนเป็น: หมดเวลาเรียกว่า! - เห็นได้ชัดว่าการอัปเดตข้อมูลถูกตรวจพบโดย Angular JS
หมายเหตุ: เราไม่ควรทำสิ่งนี้ แต่ใช้วิธีการหมดเวลาโดย Angular JS เพื่อให้มันถูกห่อหุ้มด้วยวิธีการใช้งานโดยอัตโนมัติ
วิทยาศาสตร์เป็นดาบสองคม
ในที่สุดลองมาดูวิธีการกำหนดขอบเขต () และขอบเขตวิธีการ (ฟังก์ชั่น) อีกครั้ง! แม้ว่า Angular JS ทำอะไรมากมายสำหรับเรา แต่เราก็สูญเสียโอกาสไปบ้าง คุณสามารถดูได้จาก pseudocode ต่อไปนี้:
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น $ ใช้ (expr) {
พยายาม {
ส่งคืน $ eval (expr);
} catch (e) {
$ ExceptionHandler (E);
} ในที่สุด {
$ root. $ digest ();
-
-
มันจะจับข้อยกเว้นทั้งหมดและจะไม่โยนพวกเขาอีกครั้งและในที่สุดจะเรียกวิธี $ digest ()
มาสรุปกันเถอะ
วิธี $ Apply () สามารถดำเนินการนิพจน์ JS เชิงมุมนอกกรอบเชิงมุมเช่น: เหตุการณ์ DOM, Settimeout, XHR หรือไลบรารีบุคคลที่สามอื่น ๆ นี่เป็นเพียงจุดเริ่มต้นน้ำยังคงลึกยินดีต้อนรับสู่การดำน้ำลึกด้วยกัน!