ทุกสิ่งที่คุณต้องการรู้เกี่ยวกับ ng-template, ng-content, ng-container และ * ngTemplateOutlet ใน Angular

เป็นหนึ่งในวันนั้นที่ฉันยุ่งอยู่กับการทำงานกับฟีเจอร์ใหม่สำหรับโครงการสำนักงานของฉัน ทันใดนั้นมีบางอย่างดึงดูดความสนใจของฉัน:

ในขณะที่ตรวจสอบ DOM ฉันเห็นว่าngcontentAngular ถูกนำไปใช้กับองค์ประกอบ อืม…ถ้ามันมีองค์ประกอบใน DOM สุดท้ายแล้วจะใช้อะไรล่ะ? ในเวลานั้นผมสับสนระหว่างและ

ในการแสวงหาที่จะรู้คำตอบของคำถามของฉันฉันค้นพบแนวคิดของ ที่แปลกใจของฉันก็มีเช่น*ngTemplateOutletกัน ฉันเริ่มต้นการเดินทางเพื่อค้นหาความชัดเจนเกี่ยวกับสองแนวคิด แต่ตอนนี้ฉันมีสี่ข้อซึ่งฟังดูใกล้เคียงกัน!

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

1.

เป็นชื่อที่แสดงให้เห็นเป็นองค์ประกอบแม่แบบที่ใช้เชิงมุมกับแนวทางโครงสร้าง ( *ngIf, *ngFor, [ngSwitch]และคำสั่งที่กำหนดเอง)

องค์ประกอบเทมเพลตเหล่านี้ใช้ได้เฉพาะเมื่อมีคำสั่งโครงสร้างเท่านั้น Angular จะห่อองค์ประกอบโฮสต์ (ซึ่งใช้คำสั่ง) ภายในและใช้DOM ที่เสร็จแล้วโดยแทนที่ด้วยความคิดเห็นในการวินิจฉัย

ลองพิจารณาตัวอย่างง่ายๆของ*ngIf:

*ngIfแสดงไว้ข้างต้นคือการตีความเชิงมุมของ Angular วางองค์ประกอบโฮสต์ที่ใช้คำสั่งภายในและเก็บโฮสต์ไว้ตามที่เป็นอยู่ DOM ขั้นสุดท้ายคล้ายกับที่เราเห็นในตอนต้นของบทความนี้:

การใช้งาน:

เราได้เห็นแล้วว่า Angular ใช้งานอย่างไรแต่ถ้าเราต้องการใช้ล่ะ? เนื่องจากองค์ประกอบเหล่านี้ใช้ได้เฉพาะกับคำสั่งโครงสร้างเราจึงสามารถเขียนเป็น:

นี่homeคือbooleanคุณสมบัติของส่วนประกอบที่ตั้งค่าเป็นtrueค่า ผลลัพธ์ของโค้ดด้านบนใน DOM:

ไม่มีการแสดงผล! :(

แต่ทำไมเราไม่เห็นข้อความของเราแม้ว่าจะใช้อย่างถูกต้องกับคำสั่งโครงสร้าง?

นี่คือผลลัพธ์ที่คาดหวัง ดังที่เราได้กล่าวไปแล้ว Angular จะแทนที่ด้วยความคิดเห็นในการวินิจฉัย ไม่ต้องสงสัยเลยว่าโค้ดด้านบนจะไม่สร้างข้อผิดพลาดใด ๆ เนื่องจาก Angular นั้นใช้ได้ดีกับกรณีการใช้งานของคุณ คุณจะไม่มีทางรู้ว่าเบื้องหลังเกิดอะไรขึ้น

ลองเปรียบเทียบ DOM สองตัวข้างต้นที่แสดงผลโดย Angular:

ถ้าคุณดูอย่างใกล้ชิดมีหนึ่งแท็กความคิดเห็นเป็นพิเศษใน DOM สุดท้ายของตัวอย่างที่ 2 รหัสที่ Angular ตีความคือ:

Angular ห่อโฮสต์ของคุณไว้ในอีกโฮสต์หนึ่งและแปลงไม่เพียง แต่ภายนอกเป็นความคิดเห็นในการวินิจฉัย แต่ยังรวมถึงด้านในด้วย นี่คือสาเหตุที่คุณไม่เห็นข้อความใด ๆ ของคุณ

ในการกำจัดสิ่งนี้มีสองวิธีเพื่อให้ได้ผลลัพธ์ที่คุณต้องการ:

วิธีที่ 1:

ในวิธีนี้คุณกำลังให้ Angular ด้วยรูปแบบ de-sugared ที่ไม่จำเป็นต้องมีการประมวลผลเพิ่มเติม คราวนี้ Angular จะแปลงเป็นความคิดเห็นเท่านั้น แต่ปล่อยให้เนื้อหาข้างในไม่ถูกแตะต้อง (ไม่ได้อยู่ข้างในอีกต่อไปเหมือนในกรณีก่อนหน้านี้) ดังนั้นจึงจะแสดงเนื้อหาได้อย่างถูกต้อง

หากต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้รูปแบบนี้กับคำสั่งโครงสร้างอื่น ๆ โปรดดูบทความนี้

วิธีที่ 2:

นี่เป็นรูปแบบที่มองไม่เห็นและไม่ค่อยมีใครใช้ (ใช้สองพี่น้อง) ในที่นี้เรากำลังให้การอ้างอิงเทมเพลตถึง*ngIfในthenเพื่อบอกว่าเทมเพลตใดควรใช้หากเงื่อนไขเป็นจริง

ไม่แนะนำให้ใช้หลายตัวเช่นนี้ (คุณสามารถใช้แทนได้) เนื่องจากไม่ใช่สิ่งที่หมายถึง ใช้เป็นคอนเทนเนอร์กับเทมเพลตที่สามารถใช้ซ้ำได้ในหลาย ๆ ที่ เราจะกล่าวถึงเรื่องนี้เพิ่มเติมในส่วนต่อไปของบทความนี้

2.

คุณเคยเขียนหรือเห็นรหัสที่มีลักษณะคล้ายสิ่งนี้:

เหตุผลที่พวกเราหลายคนเขียนโค้ดนี้คือไม่สามารถใช้คำสั่งโครงสร้างหลาย ๆ คำสั่งกับองค์ประกอบโฮสต์เดียวใน Angular ตอนนี้รหัสนี้ใช้งานได้ดี แต่แนะนำช่องว่างพิเศษหลายรายการใน DOM หากitem.idเป็นค่าที่ไม่ถูกต้องซึ่งอาจไม่จำเป็น

อาจไม่ต้องกังวลกับตัวอย่างง่ายๆเช่นนี้ แต่สำหรับแอปพลิเคชันขนาดใหญ่ที่มี DOM ที่ซับซ้อน (เพื่อแสดงข้อมูลนับหมื่น) สิ่งนี้อาจเป็นปัญหาเนื่องจากองค์ประกอบอาจมีผู้ฟังติดอยู่ซึ่งจะยังคงมีอยู่ใน DOM ฟังเหตุการณ์

ที่แย่ไปกว่านั้นคือระดับการซ้อนที่คุณต้องทำเพื่อใช้สไตล์ (CSS) ของคุณ!

ไม่ต้องกังวลเราต้องช่วย!

เชิงมุมเป็นองค์ประกอบการจัดกลุ่มที่ไม่ได้ยุ่งเกี่ยวกับรูปแบบหรือรูปแบบเพราะเชิงมุมไม่ได้ใส่มันได้ใน DOM

ดังนั้นถ้าเราเขียนตัวอย่างที่ 1ด้วย:

เราได้รับ DOM สุดท้ายเป็น:

ดูเรากำจัดs ว่างเหล่านั้นออกไป เราควรใช้เมื่อเราต้องการใช้คำสั่งเชิงโครงสร้างหลายคำสั่งโดยไม่ต้องแนะนำองค์ประกอบพิเศษใด ๆ ใน DOM ของเรา

สำหรับข้อมูลเพิ่มเติมโปรดดูเอกสาร มีกรณีการใช้งานอื่นที่ใช้ในการฉีดเทมเพลตลงในหน้าแบบไดนามิก ฉันจะกล่าวถึงกรณีการใช้งานนี้ในส่วนสุดท้ายของบทความนี้

3.

ใช้เพื่อสร้างส่วนประกอบที่กำหนดค่าได้ ซึ่งหมายความว่าส่วนประกอบต่างๆสามารถกำหนดค่าได้ตามความต้องการของผู้ใช้ นี้เป็นที่รู้จักกันดีในฐานะฉายเนื้อหา คอมโพเนนต์ที่ใช้ในไลบรารีที่เผยแพร่ใช้เพื่อทำให้สามารถกำหนดค่าได้เอง

พิจารณาองค์ประกอบง่ายๆ:

เนื้อหา HTML ที่ส่งผ่านภายในแท็กเปิดและปิดของคอมโพเนนต์คือเนื้อหาที่จะฉาย นี่คือสิ่งที่เราเรียกว่าฉายเนื้อหา เนื้อหาจะแสดงผลภายในองค์ประกอบภายใน สิ่งนี้ช่วยให้ผู้บริโภคของคอมโพเนนต์สามารถส่งผ่านส่วนท้ายที่กำหนดเองภายในคอมโพเนนต์และควบคุมว่าต้องการให้แสดงผลอย่างไร

การคาดการณ์หลายรายการ:

จะเป็นอย่างไรหากคุณสามารถตัดสินใจได้ว่าควรวางเนื้อหาไว้ที่ใด แทนที่จะเนื้อหาทุกที่คาดการณ์ภายในเดียวคุณยังสามารถควบคุมวิธีการที่เนื้อหาจะได้รับการคาดการณ์ที่มีแอตทริบิวต์ของselect ต้องใช้ตัวเลือกองค์ประกอบในการตัดสินใจว่าจะฉายเนื้อหาใดภายในรายการใดรายการหนึ่ง

วิธีการมีดังนี้

เราได้แก้ไขคำจำกัดความเพื่อทำการฉายภาพหลายเนื้อหา แอตทริบิวต์เลือกประเภทของเนื้อหาที่จะแสดงผลภายในโดยเฉพาะอย่างยิ่งselect ที่นี่เราต้องselectแสดงh1องค์ประกอบส่วนหัวก่อน หากเนื้อหาที่ฉายไม่มีh1องค์ประกอบจะไม่แสดงผลอะไรเลย ในทำนองเดียวกันที่สองselectมองหาไฟล์div. ส่วนที่เหลือของเนื้อหาที่ได้รับการแสดงผลภายในที่ผ่านมาไม่มีselect

การเรียกส่วนประกอบจะมีลักษณะดังนี้:

4. * ngTemplateOutlet

…พวกมันถูกใช้เป็นคอนเทนเนอร์กับเทมเพลตที่สามารถใช้ซ้ำได้ในหลาย ๆ ที่ เราจะกล่าวถึงเรื่องนี้เพิ่มเติมในส่วนต่อไปของบทความนี้

…มีอีกกรณีหนึ่งที่ใช้ในการฉีดเทมเพลตแบบไดนามิกลงในหน้าเว็บ ฉันจะกล่าวถึงกรณีการใช้งานนี้ในส่วนสุดท้ายของบทความนี้

นี่คือส่วนที่เราจะพูดถึงสองประเด็นข้างต้นที่กล่าวถึงก่อนหน้านี้ *ngTemplateOutletใช้สำหรับสองสถานการณ์ - เพื่อแทรกเทมเพลตทั่วไปในส่วนต่างๆของมุมมองโดยไม่คำนึงถึงลูปหรือเงื่อนไขและเพื่อสร้างองค์ประกอบที่กำหนดค่าไว้สูง

การใช้แม่แบบซ้ำ:

พิจารณามุมมองที่คุณต้องแทรกเทมเพลตในหลาย ๆ ที่ ตัวอย่างเช่นโลโก้ บริษัท ที่จะวางไว้ในเว็บไซต์ เราสามารถบรรลุได้โดยการเขียนเทมเพลตสำหรับโลโก้เพียงครั้งเดียวและนำกลับมาใช้ซ้ำได้ทุกที่ภายในมุมมอง

ต่อไปนี้เป็นข้อมูลโค้ด:

อย่างที่คุณเห็นเราเขียนเทมเพลตโลโก้เพียงครั้งเดียวและใช้สามครั้งในหน้าเดียวกันด้วยรหัสบรรทัดเดียว!

*ngTemplateOutletยังยอมรับอ็อบเจ็กต์บริบทซึ่งสามารถส่งผ่านเพื่อปรับแต่งเอาต์พุตเทมเพลตทั่วไป สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวัตถุบริบทโปรดดูที่เอกสารอย่างเป็นทางการ

ส่วนประกอบที่ปรับแต่งได้:

กรณีการใช้งานที่สองสำหรับ*ngTemplateOutletส่วนประกอบที่ปรับแต่งได้สูง พิจารณาตัวอย่างส่วนประกอบก่อนหน้าของเราด้วยการปรับเปลี่ยนบางอย่าง:

ดังกล่าวข้างต้นเป็นรุ่นที่ปรับเปลี่ยนองค์ประกอบที่รับคุณสมบัติการป้อนข้อมูลสาม -  headerTemplate, ,bodyTemplate footerTemplateต่อไปนี้เป็นข้อมูลโค้ดสำหรับproject-content.ts:

สิ่งที่เรากำลังพยายามที่จะบรรลุที่นี่คือการแสดงให้เห็นส่วนหัวและส่วนท้ายของร่างกายเป็นที่ได้รับจากแม่ขององค์ประกอบ หากไม่มีให้ส่วนประกอบของเราจะแสดงเทมเพลตเริ่มต้นแทน ดังนั้นการสร้างส่วนประกอบที่กำหนดเองได้สูง

ในการใช้ส่วนประกอบที่แก้ไขล่าสุดของเรา:

นี่คือวิธีที่เราจะส่งเทมเพลตอ้างอิงไปยังส่วนประกอบของเรา หากไม่ผ่านรายการใดรายการหนึ่งส่วนประกอบจะแสดงเทมเพลตเริ่มต้น

ng-content เทียบกับ * ngTemplateOutlet

ทั้งสองอย่างช่วยให้เราได้ส่วนประกอบที่มีการปรับแต่งสูง แต่จะเลือกแบบไหนและเมื่อใด

จะเห็นได้ชัดเจนว่า*ngTemplateOutletทำให้เรามีอำนาจมากขึ้นในการแสดงเทมเพลตเริ่มต้นหากไม่มีให้

ng-contentนี้ไม่ได้เป็นกรณีที่มี แสดงเนื้อหาตามที่เป็นอยู่ คุณสามารถแบ่งเนื้อหาและแสดงผลในตำแหน่งต่างๆในมุมมองของคุณได้สูงสุดโดยใช้selectแอตทริบิวต์ คุณไม่สามารถแสดงเนื้อหาภายในแบบมีng-contentเงื่อนไขได้ คุณต้องแสดงเนื้อหาที่ได้รับจากผู้ปกครองโดยไม่จำเป็นต้องตัดสินใจตามเนื้อหา

อย่างไรก็ตามการเลือกระหว่างสองอย่างนั้นขึ้นอยู่กับกรณีการใช้งานของคุณ อย่างน้อยตอนนี้เรามีอาวุธใหม่*ngTemplateOutletในคลังแสงของเราซึ่งให้การควบคุมเนื้อหามากขึ้นนอกเหนือจากคุณสมบัติของng-content!