เป็นคำถามที่ยอดเยี่ยม! ฉันชอบที่จะได้ยินสิ่งที่คนอื่นพูด แต่นี่เป็นแนวทางที่ฉันใช้
สถานที่ตั้งสูง: ขอบเขตถูกใช้เป็น "กาว" ที่เราใช้ในการสื่อสารระหว่างตัวควบคุมหลักคำสั่งและแม่แบบคำสั่ง
ขอบเขตหลัก: scope: false
ดังนั้นจึงไม่มีขอบเขตใหม่เลย
ฉันไม่ได้ใช้สิ่งนี้บ่อยนัก แต่อย่างที่ @MarkRajcok กล่าวว่าหากคำสั่งไม่สามารถเข้าถึงตัวแปรขอบเขต (และไม่ได้ตั้งค่าแน่นอน!) นี่เป็นสิ่งที่ดีเท่าที่ฉันกังวล สิ่งนี้ยังเป็นประโยชน์สำหรับคำสั่งเด็กที่ใช้เฉพาะในบริบทของคำสั่งหลัก (แม้ว่าจะมีข้อยกเว้นนี้เสมอ) และไม่มีเทมเพลต โดยพื้นฐานแล้วสิ่งใดก็ตามที่มีเทมเพลตไม่ได้อยู่ในขอบเขตการแบ่งปันเพราะคุณเปิดเผยขอบเขตสำหรับการเข้าถึงและการจัดการโดยเนื้อแท้ (แต่ฉันแน่ใจว่ามีข้อยกเว้นสำหรับกฎนี้)
ตัวอย่างเช่นเมื่อเร็ว ๆ นี้ฉันได้สร้างคำสั่งที่ดึงกราฟิกแบบเวกเตอร์ (สแตติก) โดยใช้ไลบรารี SVG ฉันกำลังอยู่ระหว่างการเขียน มัน$observe
เป็นคุณสมบัติสองอย่าง ( width
และheight
) และใช้ในการคำนวณ แต่ไม่ได้ตั้งค่าหรืออ่านตัวแปรขอบเขตใด ๆ และไม่มีแม่แบบ นี่เป็นกรณีการใช้งานที่ดีสำหรับการไม่สร้างขอบเขตอื่น เราไม่จำเป็นต้องใช้หนึ่งดังนั้นทำไมต้องรำคาญ?
แต่ในคำสั่ง SVG อื่นฉันต้องการชุดข้อมูลที่จะใช้และต้องมีการเก็บสถานะเล็กน้อย ในกรณีนี้การใช้ขอบเขตหลักจะไม่รับผิดชอบ (อีกครั้งโดยทั่วไปจะพูด) ดังนั้นแทนที่จะ ...
ขอบเขตของเด็ก: scope: true
คำสั่งที่มีขอบเขตลูกจะรับรู้บริบทและมีจุดประสงค์ที่จะโต้ตอบกับขอบเขตปัจจุบัน
เห็นได้ชัดว่าข้อได้เปรียบที่สำคัญของสิ่งนี้ในขอบเขตแยกคือผู้ใช้มีอิสระที่จะใช้การแก้ไขในคุณลักษณะใด ๆ ที่พวกเขาต้องการ; เช่นใช้class="item-type-{{item.type}}"
ในคำสั่งที่มีขอบเขตแยกจะไม่ทำงานโดยค่าเริ่มต้น แต่ทำงานได้ดีในหนึ่งกับขอบเขตเด็กเพราะสิ่งที่มีการแก้ไขสามารถยังคงโดยค่าเริ่มต้นจะพบในขอบเขตผู้ปกครอง นอกจากนี้คำสั่งยังสามารถประเมินคุณลักษณะและการแสดงออกในบริบทของขอบเขตของตนเองอย่างปลอดภัยโดยไม่ต้องกังวลเกี่ยวกับมลภาวะหรือความเสียหายต่อผู้ปกครอง
ตัวอย่างเช่นคำแนะนำเครื่องมือเป็นสิ่งที่เพิ่งได้รับการเพิ่ม; ขอบเขตการแยกจะไม่ทำงาน (โดยค่าเริ่มต้นโปรดดูด้านล่าง) เพราะคาดว่าเราจะใช้คำสั่งอื่นหรือแอตทริบิวต์การแก้ไขที่นี่ เคล็ดลับเครื่องมือเป็นเพียงการปรับปรุง แต่คำแนะนำเครื่องมือต้องตั้งค่าบางอย่างบนขอบเขตเพื่อใช้กับคำสั่งย่อยและ / หรือแม่แบบและเห็นได้ชัดว่าการจัดการสถานะของตนเองดังนั้นจึงค่อนข้างแย่ในการใช้ขอบเขตหลัก เรากำลังก่อมลภาวะหรือทำลายมัน
ฉันพบว่าตัวเองใช้ขอบเขตเด็กบ่อยครั้งกว่าแยกหรือเป็นขอบเขตหลัก
แยกขอบเขต: scope: {}
ใช้สำหรับส่วนประกอบที่นำมาใช้ซ้ำได้ :-)
แต่อย่างจริงจังฉันคิดว่า "ส่วนประกอบที่ใช้ซ้ำได้" เป็น "ส่วนประกอบที่มีในตัว" ความตั้งใจคือจะต้องใช้เพื่อจุดประสงค์เฉพาะดังนั้นการรวมเข้ากับคำสั่งอื่นหรือเพิ่มแอตทริบิวต์การแก้ไขอื่น ๆ ไปยังโหนด DOM โดยเนื้อแท้ไม่สมเหตุสมผล
หากต้องการข้อมูลเฉพาะเพิ่มเติมสิ่งใดที่จำเป็นสำหรับฟังก์ชันการทำงานแบบสแตนด์อโลนนี้มีให้ผ่านคุณสมบัติที่ระบุซึ่งประเมินในบริบทของขอบเขตพาเรนต์ พวกเขาอาจเป็นสตริงทางเดียว ('@'), การแสดงออกทางเดียว ('&') หรือการผูกตัวแปรสองทาง ('=')
ในส่วนประกอบที่มีอยู่ในตัวมันไม่เหมาะสมที่จะต้องใช้คำสั่งหรือคุณสมบัติอื่น ๆ เพราะมันมีอยู่โดยตัวมันเอง สไตล์ของมันจะถูกควบคุมโดยแม่แบบของตัวเอง (ถ้าจำเป็น) และสามารถมีการแปลงเนื้อหาที่เหมาะสม (ถ้าจำเป็น) เป็นแบบสแตนด์อโลนดังนั้นเราจึงวางไว้ในขอบเขตไอโซเลตเพื่อพูดว่า: "อย่ายุ่งกับสิ่งนี้ฉันจะให้ API ที่กำหนดไว้แก่คุณผ่านแอตทริบิวต์บางอย่าง"
แนวปฏิบัติที่ดีที่สุดคือการแยกสิ่งที่ใช้เทมเพลตออกจากฟังก์ชั่น directive link และ controller ให้มากที่สุด นี่เป็นอีกจุดกำหนดค่า "API-like": ผู้ใช้ของคำสั่งสามารถแทนที่เทมเพลตได้! ฟังก์ชันการทำงานทั้งหมดยังคงเหมือนเดิมและ API ภายในก็ไม่เคยสัมผัส แต่เราสามารถยุ่งกับการออกแบบและการใช้งาน DOM ได้มากเท่าที่เราต้องการ ui / bootstrap เป็นตัวอย่างที่ดีของวิธีการทำเช่นนี้เพราะ Peter & Pawel ยอดเยี่ยม
ขอบเขตการแยกนั้นยังยอดเยี่ยมสำหรับการใช้กับ transclusion ใช้แท็บ; มันไม่ได้เป็นเพียงฟังก์ชั่นทั้งหมด แต่สิ่งที่อยู่ภายในนั้นสามารถประเมินได้อย่างอิสระจากภายในขอบเขตหลักในขณะที่ปล่อยให้แท็บ (และบานหน้าต่าง) ทำสิ่งที่พวกเขาต้องการ แท็บมีสถานะของตนเองอย่างชัดเจนซึ่งอยู่ในขอบเขต (เพื่อโต้ตอบกับเทมเพลต) แต่สถานะนั้นไม่มีส่วนเกี่ยวข้องกับบริบทที่ใช้งานอยู่ - ภายในทั้งหมดเป็นสิ่งที่ทำให้คำสั่งแท็บเป็นคำสั่งของแท็บ นอกจากนี้มันไม่สมเหตุสมผลในการใช้คำสั่งอื่น ๆ กับแท็บ พวกเขาเป็นแท็บ - และเราได้รับฟังก์ชั่นนั้นมาแล้ว!
ล้อมรอบด้วยฟังก์ชั่นเพิ่มเติมหรือแปลงฟังก์ชั่นอื่น ๆ อีกมากมาย แต่คำสั่งคือสิ่งที่มันมีอยู่แล้ว
ทั้งหมดที่กล่าวว่าฉันควรทราบว่ามีข้อ จำกัด บางอย่าง (เช่นคุณสมบัติ) ของขอบเขตไอโซเลทตามที่ @ProLoser พูดถึงในคำตอบของเขา ตัวอย่างเช่นในส่วนขอบเขตลูกฉันได้กล่าวถึงการแก้ไขในคุณลักษณะที่ไม่ใช่คำสั่งที่แบ่งเมื่อใช้ขอบเขต isolate (โดยค่าเริ่มต้น) ตัวอย่างเช่นผู้ใช้สามารถทำได้เพียงแค่ใช้class="item-type-{{$parent.item.type}}"
และมันจะทำงานได้อีกครั้ง ดังนั้นหากมีเหตุผลที่น่าสนใจที่จะใช้ขอบเขตแบบแยกต่างหากบนขอบเขตของเด็ก แต่คุณเป็นห่วงเกี่ยวกับข้อ จำกัด เหล่านี้รู้ว่าคุณสามารถแก้ไขได้ทั้งหมดหากคุณต้องการ
สรุป
คำสั่งที่ไม่มีขอบเขตใหม่เป็นแบบอ่านอย่างเดียว พวกเขาเชื่อถือได้อย่างสมบูรณ์ (เช่นภายในแอพ) และไม่แตะที่แจ็ค คำสั่งที่มีขอบเขตลูกจะเพิ่มฟังก์ชันการทำงาน แต่ไม่ได้เป็นเพียงฟังก์ชันการทำงานเท่านั้น สุดท้ายแยกขอบเขตสำหรับคำสั่งที่เป็นเป้าหมายทั้งหมด มันเป็นแบบสแตนด์อโลนดังนั้นจึงไม่เป็นไร (และส่วนใหญ่ "ถูกต้อง") เพื่อให้พวกเขาโกง
ฉันต้องการที่จะเริ่มต้นความคิดของฉันออกมา แต่เมื่อฉันคิดถึงสิ่งต่าง ๆ เพิ่มเติมฉันจะอัปเดตสิ่งนี้ แต่อึศักดิ์สิทธิ์ - นี่เป็นเวลานานสำหรับคำตอบ SO ...
PS: วงสัมผัสทั้งหมด แต่เนื่องจากเรากำลังพูดถึงขอบเขตฉันชอบพูดว่า "prototypical" ในขณะที่คนอื่นชอบ "prototypal" ซึ่งดูเหมือนว่าจะแม่นยำมากขึ้น แต่เพิ่งปิดลิ้นไม่ดีเลย :-)