AngularJS ng-include: การรวมไฟล์ HTML พร้อมตัวอย่าง
⚡ สรุปอย่างชาญฉลาด
คำสั่ง `ng-include` ใน AngularJS จะดึงข้อมูล รวบรวม และแทรกส่วนของ HTML ภายนอกเข้าไปในหน้าหลัก ทำให้มาร์กอัปที่ใช้ร่วมกัน เช่น ตาราง ส่วนหัว หรือส่วนท้าย อยู่ในไฟล์ย่อยที่นำกลับมาใช้ซ้ำได้ไฟล์เดียว
ตามค่าเริ่มต้น HTML ไม่ได้จัดเตรียมสิ่งอำนวยความสะดวกในการรวมโค้ดฝั่งไคลเอ็นต์จากไฟล์อื่น โดยปกติแล้ว แนวทางปฏิบัติที่ดีในภาษาการเขียนโปรแกรมใดๆ ก็ตามคือการกระจายฟังก์ชันการทำงานไปยังไฟล์ต่างๆ สำหรับแอปพลิเคชันใดๆ
ตัวอย่างเช่น หากคุณมีตรรกะสำหรับการดำเนินการทางตัวเลข โดยปกติแล้วคุณจะต้องการกำหนดฟังก์ชันการทำงานนั้นไว้ในไฟล์แยกต่างหากหนึ่งไฟล์ จากนั้นจึงสามารถนำไฟล์แยกต่างหากนั้นมาใช้ซ้ำในแอปพลิเคชันต่างๆ ได้โดยการเพียงแค่รวมไฟล์นั้นไว้
โดยปกติจะเป็นแนวคิดของ รวมข้อความ ซึ่งมีจำหน่ายใน การเขียนโปรแกรมภาษา เช่น .Net และ Java.
บทช่วยสอนนี้จะกล่าวถึงวิธีการอื่นๆ ในการจัดการไฟล์ (ไฟล์ที่มีข้อมูลภายนอก) HTML สามารถใส่โค้ดลงในไฟล์ HTML หลักได้
ฝั่งไคลเอ็นต์ประกอบด้วย
หนึ่งในวิธีที่พบบ่อยที่สุดในการแทรกโค้ด HTML คือผ่านทาง Javaต้นฉบับ Javaต้นฉบับ เป็นภาษาโปรแกรมที่สามารถใช้เพื่อจัดการเนื้อหาในหน้า HTML ได้ทันที เพราะฉะนั้น, Javaสคริปต์ยังสามารถใช้เพื่อรวมโค้ดจากไฟล์อื่นได้อีกด้วย
ขั้นตอนด้านล่างนี้แสดงให้เห็นถึงวิธีการดำเนินการดังกล่าว
ขั้นตอน 1) กำหนดไฟล์ชื่อ Sub.html และเพิ่มโค้ดต่อไปนี้ลงในไฟล์
<div> This is an included file </div>
ขั้นตอน 2) สร้างไฟล์ชื่อ Sample.html ซึ่งเป็นไฟล์แอปพลิเคชันหลักของคุณ และเพิ่มข้อมูลโค้ดด้านล่าง
ด้านล่างนี้เป็นประเด็นหลักที่ควรทราบเกี่ยวกับโค้ดด้านล่าง
- ในแท็ก body จะมีแท็ก div ซึ่งมีรหัสเนื้อหา นี่คือตำแหน่งที่จะแทรกโค้ดจากไฟล์ภายนอก 'Sub.html'
- มีการอ้างอิงถึงสคริปต์ jQuery jQuery เป็นภาษาสคริปต์ที่สร้างขึ้นบนพื้นฐานของ Javaสคริปต์ที่ทำให้การจัดการ DOM ง่ายยิ่งขึ้น
- ตัว Vortex Indicator ได้ถูกนำเสนอลงในนิตยสาร Javaในฟังก์ชันสคริปต์ มีคำสั่ง '$(“#Content”).load(“Sub.html”);' ซึ่งจะทำให้โค้ดในไฟล์ Sub.html ถูกแทรกเข้าไปในแท็ก div ที่มี id เป็น Content
<html> <head> <script src="jquery.js"></script> <script> $(function(){ $("#Content").load("Sub.html"); }); </script> </head> <body> <div id="Content"></div> </body> </html>
ฝั่งเซิร์ฟเวอร์รวมอยู่ด้วย
การรวมฝั่งเซิร์ฟเวอร์ยังพร้อมใช้งานสำหรับการรวมโค้ดทั่วไปทั่วทั้งไซต์ โดยปกติจะทำเพื่อรวมเนื้อหาในส่วนด้านล่างของเอกสาร HTML
- ส่วนหัวของหน้า
- ส่วนท้ายของหน้า
- เมนูนำทาง
เพื่อให้เว็บเซิร์ฟเวอร์รู้จักไฟล์ Server Side Include ไฟล์นั้นจะต้องมีนามสกุลพิเศษ ซึ่งโดยทั่วไปแล้วเว็บเซิร์ฟเวอร์จะยอมรับได้ เช่น .shtml, .stm, .shtm, .cgi
คำสั่งที่ใช้ในการรวมเนื้อหาคือ "คำสั่ง include" ตัวอย่างของคำสั่ง include แสดงอยู่ด้านล่าง:
<!--#include virtual="navigation.cgi" -->
- คำสั่งข้างต้นอนุญาตให้รวมเนื้อหาของเอกสารหนึ่งไว้ในอีกเอกสารหนึ่งได้
- โค้ดคำสั่ง "เสมือน" ด้านบนใช้เพื่อระบุเป้าหมายที่สัมพันธ์กับรูทโดเมนของแอปพลิเคชัน
- นอกจากนี้ สำหรับพารามิเตอร์เสมือน ยังมีพารามิเตอร์ไฟล์ที่สามารถใช้ได้อีกด้วย พารามิเตอร์ "ไฟล์" จะใช้เมื่อจำเป็นต้องระบุเส้นทางที่สัมพันธ์กับไดเร็กทอรีของไฟล์ปัจจุบัน
หมายเหตุ
พารามิเตอร์เสมือนใช้เพื่อระบุไฟล์ (หน้า HTML, ไฟล์ข้อความ, สคริปต์ ฯลฯ) ที่ต้องการรวมไว้ หากกระบวนการของเว็บเซิร์ฟเวอร์ไม่สามารถเข้าถึงเพื่ออ่านไฟล์หรือรันสคริปต์ คำสั่งรวมจะล้มเหลว คำ 'เสมือน' คือคำหลักที่ต้องวางไว้ในคำสั่งรวม
วิธีรวมไฟล์ HTML ใน AngularJS
AngularJS มีฟังก์ชันที่ช่วยให้สามารถรวมฟังก์ชันการทำงานจากไฟล์ AngularJS อื่นๆ ได้โดยใช้คำสั่ง `ng-include` คำสั่ง.
จุดประสงค์หลักของ "คำสั่ง ng-include" คือการดึงข้อมูล รวบรวม และรวมส่วนของ HTML ภายนอกเข้ากับแอปพลิเคชัน AngularJS หลัก
หมายเหตุเกี่ยวกับเวอร์ชัน: AngularJS 1.x สิ้นสุดการสนับสนุนระยะยาว (Long Term Support) เมื่อวันที่ 31 ธันวาคม 2021 และทีมผู้พัฒนาเฟรมเวิร์กได้ระบุว่า การสนับสนุน AngularJS สิ้นสุดลงอย่างเป็นทางการแล้ว ในเดือนมกราคม 2022 ดังนั้นจึงไม่มีการอัปเดตหรือแพตช์ความปลอดภัยใดๆ ตามมา ทุกขั้นตอนและบล็อกโค้ดด้านล่างจะยังคงเหมือนเดิมทุกประการ เพื่อเป็นข้อมูลอ้างอิงทางประวัติศาสตร์ Angular เวอร์ชันใหม่ไม่มีตัวทดแทนโดยตรง: โครงสร้างมาร์กอัปประกอบขึ้นจากคอมโพเนนต์ และแฟรกเมนต์ที่เลือกในขณะรันไทม์จะถูกเรนเดอร์ด้วย ng-container และ ngComponentOutlet.
มาดูโค้ดด้านล่างนี้และอธิบายวิธีการที่จะทำให้สำเร็จโดยใช้ AngularJS กัน
ขั้นตอน 1) มาเขียนโค้ดด้านล่างนี้ในไฟล์ชื่อ Table.html นี่คือไฟล์ที่จะถูกแทรกลงในไฟล์แอปพลิเคชันหลักของเราโดยใช้คำสั่ง ng-include
โค้ดตัวอย่างด้านล่างนี้สมมติว่ามีตัวแปรขอบเขตชื่อ “tutorial” อยู่ จากนั้นจึงใช้ตัวแปรดังกล่าว ng-ซ้ำ คำสั่งนี้จะวนไปทีละหัวข้อในตัวแปร “tutorial” และแสดงค่าสำหรับ 'Name' และ 'Descriptคู่คีย์-ค่าของ ion
<table>
<tr ng-repeat="Topic in tutorial">
<td>{{ Topic.Name }}</td>
<td>{{ Topic.Description }}</td>
</tr>
</table>
ขั้นตอน 2) มาเขียนโค้ดด้านล่างนี้ลงในไฟล์ชื่อ Main.html กัน นี่คือแอปพลิเคชัน AngularJS อย่างง่ายที่มีลักษณะดังต่อไปนี้
- ใช้คำสั่ง “ng-include” เพื่อแทรกโค้ดในไฟล์ภายนอก 'Table.html' ข้อความดังกล่าวได้รับการเน้นด้วยตัวหนาในโค้ดด้านล่าง ดังนั้นแท็ก div ' - จะถูกแทนที่ด้วยโค้ดทั้งหมดในไฟล์ 'Table.html'
- ตัว Vortex Indicator ได้ถูกนำเสนอลงในนิตยสาร ตัวควบคุมตัวแปร “tutorial” จะถูกสร้างขึ้นเป็นส่วนหนึ่งของออบเจ็กต์ $scope ตัวแปรนี้ประกอบด้วยรายการคู่คีย์-ค่า
ในตัวอย่างของเรา คู่ค่าคีย์คือ
- ชื่อ – หมายถึงชื่อของหัวข้อ เช่น ตัวควบคุม โมเดล และคำสั่ง
- Descriptไอออน – อธิบายหัวข้อแต่ละหัวข้อ
ตัวแปรบทช่วยสอนยังเข้าถึงได้ในไฟล์ 'Table.html'
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Event Registration</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
</head>
<body ng-app="sampleApp">
<div ng-controller="AngularController">
<h3> Guru99 Global Event</h3>
<div ng-include="'Table.html'"></div>
</div>
<script>
var sampleApp = angular.module('sampleApp',[]);
sampleApp.controller('AngularController', function($scope) {
$scope.tutorial =[
{Name: "Controllers" , Description : "Controllers in action"},
{Name: "Models" , Description : "Models and binding data"},
{Name: "Directives" , Description : "Flexibility of Directives"}
];
});
</script>
</body>
</html>
เมื่อคุณรันโค้ดข้างต้นคุณจะได้รับผลลัพธ์ดังต่อไปนี้
เอาท์พุต:
ภาพหน้าจอด้านล่างแสดงผลลัพธ์ที่แสดงผล: แท็บเบราว์เซอร์มีชื่อว่า "การลงทะเบียนกิจกรรม" หัวข้ออยู่เหนือตารางที่แทรกเข้ามา และสามแถวถูกดึงมาจากอาร์เรย์ตัวอย่างในไฟล์ Main.html ผ่านทาง partial ภาพหน้าจอที่มีคำอธิบายประกอบแสดงหัวข้อว่า Gur99 ในขณะที่โค้ดเขียนว่า Guru99.
แอตทริบิวต์ของ ng-include ได้แก่ src, onload และ autoscroll
นอกเหนือจากชื่อไฟล์แล้ว คำสั่งนี้ยังรับแอตทริบิวต์เสริมอีกสองรายการ และสามารถเขียนได้สามวิธี ได้แก่ เป็นแอตทริบิวต์บนองค์ประกอบใดๆ หรือเป็น <ng-include> องค์ประกอบ หรือเป็นคลาส CSS ข้อมูลอ้างอิงด้านล่างนี้เป็นไปตามมาตรฐานอย่างเป็นทางการ เอกสารประกอบ ngInclude.
| คุณลักษณะ | ต้อง | สิ่งที่มันไม่ |
|---|---|---|
| src หรือ ng-include | มี (ใบกำกับภาษีเต็มรูปแบบ) | นิพจน์ที่ประเมินค่าได้ตรงกับเทมเพลต URL |
| กำลังโหลด | ไม่ | นิพจน์จะถูกประเมินทุกครั้งที่การโหลดส่วนย่อยใหม่เสร็จสิ้น |
| การเลื่อนอัตโนมัติ | ไม่ | เรียกใช้ $anchorScroll หลังจากโหลดเนื้อหาเสร็จแล้ว การละเว้นแอตทริบิวต์นี้จะปิดใช้งานการเลื่อน |
<div ng-include="'Table.html'" onload="loaded = true" autoscroll></div> <ng-include src="templateUrl"></ng-include>
ข้อผิดพลาดที่พบบ่อยที่สุดมาจากแถวแรก: src ใช้เวลาและ การแสดงออกไม่ใช่สตริงธรรมดา ดังนั้นเส้นทางตัวอักษรจึงต้องมีเครื่องหมายคำพูดอยู่ภายในแอตทริบิวต์ ซึ่งเป็นเหตุผลว่าทำไมตัวอย่างข้างต้นจึงอ่านว่า ng-include="'Table.html'". การเขียน ng-include="Table.html" ทำให้ AngularJS ประเมินผล Table ในฐานะคุณสมบัติของขอบเขต ให้ค้นหาไม่พบอะไรเลย และปล่อยให้องค์ประกอบนั้นว่างเปล่า
เหตุใด ng-include จึงสร้างขอบเขตย่อยใหม่
คำสั่งนี้จะไม่วางมาร์กอัปลงในขอบเขตโดยรอบ การรวมแต่ละครั้งจะสร้างลูกใหม่ ขอบเขต ซึ่งสืบทอดมาจากขอบเขตที่ประกาศไว้ และข้อเท็จจริงเพียงข้อเดียวนี้อธิบายถึงความประหลาดใจที่มีผลผูกพันส่วนใหญ่ได้
การอ่านทำงานได้ตามที่คาดไว้ ข้อความบางส่วนด้านบนอ่านได้ดังนี้ tutorial มาจากผู้ปกครองโดยตรง ซึ่งเป็นเหตุผลว่าทำไม ng-repeat พบอาร์เรย์ ปัญหาอยู่ที่การเขียน: เมื่อการกำหนดค่าบางส่วนให้กับประเภทข้อมูลพื้นฐาน เช่นเดียวกับ ng-model="topic"AngularJS สร้าง topic ในขอบเขตของเด็ก สำเนาของผู้ปกครองจะไม่เปลี่ยนแปลง
มีสองพฤติกรรมที่จะช่วยหลีกเลี่ยงกับดักนี้:
- ผูกผ่านวัตถุ เช่น
ng-model="data.topic"ดังนั้นทั้งผู้ปกครองและเด็กจึงเข้าถึงข้อมูลอ้างอิงเดียวกัน - เก็บสถานะไว้ในคอนโทรลเลอร์หรือเซอร์วิส แล้วเปิดเผยฟังก์ชันแทนที่จะใช้ค่าพื้นฐานแบบเปล่าๆ
ส่วนประกอบนี้ยังปล่อยสัญญาณออกมาด้วย $includeContentRequested, $includeContentLoaded และ $includeContentErrorดังนั้นผู้ปกครองจึงสามารถตอบสนองได้ผ่านทาง $scope.$on โดยไม่เข้าไปยุ่งเกี่ยวกับเด็กเลยแม้แต่น้อย
วิธีแก้ไขปัญหา ng-include ว่างเปล่าหรือล้มเหลว
คำสั่ง include ที่ไม่สร้างผลลัพธ์ใดๆ มักล้มเหลวด้วยเหตุผลบางประการ ลองตรวจสอบทีละข้อตามลำดับนี้
- ตรวจสอบใบเสนอราคา ชื่อไฟล์ที่ถูกต้องจะต้องมีเครื่องหมายอัญประกาศเดี่ยวอยู่ภายในค่าแอตริบิวต์ หากไม่มีเครื่องหมายอัญประกาศเดี่ยว ค่าที่ได้จะเป็น undefined และจะไม่มีการส่งคำขอใดๆ
- แสดงผลหน้าเว็บผ่าน HTTP คำสั่งดังกล่าวจะส่งคำขอ XHR สำหรับไฟล์ย่อย ดังนั้นการเปิดไฟล์ Main.html โดยตรงจากดิสก์ผ่านที่อยู่ไฟล์จึงล้มเหลวในเบราว์เซอร์ส่วนใหญ่ แต่เว็บเซิร์ฟเวอร์ภายในเครื่องจะแก้ไขปัญหานี้ได้
- ตรวจสอบว่าเส้นทางถูกต้องหรือไม่ สังเกตแผงเครือข่ายเพื่อดูคำขอ หากพบรหัส 404 หมายความว่าเส้นทางนั้นเป็นแบบสัมพัทธ์กับหน้าเว็บที่โฮสต์ไฟล์ที่รวมเข้ามา ไม่ใช่กับไฟล์ย่อยที่อ้างอิงถึงไฟล์นั้น
- เคารพกฎว่าด้วยแหล่งกำเนิดเดียวกัน โดยค่าเริ่มต้น เทมเพลต URL ต้องตรงกับโดเมนและโปรโตคอลของเอกสารแอปพลิเคชัน เนื่องจาก AngularJS จะส่งผ่านไป $sce.getTrustedResourceUrlแม่แบบจากแหล่งอื่นจำเป็นต้องมีรายการในแหล่งข้อมูลที่เชื่อถือได้ URL หรือใช้ลิสต์ หรือตัวห่อ trustAsResourceUrl ที่ระบุอย่างชัดเจน และเซิร์ฟเวอร์ระยะไกลยังคงต้องส่งส่วนหัว CORS อยู่ดี
- จงฟังเสียงแห่งความล้มเหลว $includeContentError จะทำงานเมื่อใดก็ตามที่สถานะการตอบกลับอยู่นอกช่วง 200 ถึง 299 โดยจะเปลี่ยนพื้นที่ว่างเปล่าที่ไม่มีการแจ้งเตือนใดๆ ให้กลายเป็นข้อความที่ควรบันทึกไว้
อีกสาเหตุหนึ่งที่มองข้ามได้ง่ายคือ AngularJS จะเก็บ partial ที่ดึงมาทั้งหมดไว้ใน $templateCache ดังนั้นไฟล์ที่แก้ไขแล้วอาจยังคงแสดงมาร์กอัปที่ล้าสมัยต่อไปจนกว่ารายการในแคชจะถูกลบออกหรือหน้าเว็บจะถูกโหลดใหม่จากซอร์สโค้ด เมื่อ fragment ต้องการพฤติกรรมของตัวเองมากกว่าแค่มาร์กอัปอย่างเดียว... คำสั่งแบบกำหนดเอง เครื่องมือที่มีเทมเพลตเฉพาะและขอบเขตการทำงานที่แยกต่างหากนั้นเป็นเครื่องมือที่ดีกว่า

