AngularJS ng-view พร้อมตัวอย่าง

⚡ สรุปอย่างชาญฉลาด

ใน AngularJS มุมมอง (Views) ช่วยให้หน้าเว็บหนึ่งหน้าสามารถเปลี่ยนเนื้อหาได้แทนที่จะต้องเปลี่ยนหน้าใหม่ ซึ่งเป็นสิ่งที่ทำให้แอปพลิเคชันแบบหน้าเดียว (Single Page Application) ให้ความรู้สึกรวดเร็วทันใจ คำสั่ง `ng-view` จะกำหนดขอบเขตที่แต่ละเส้นทางจะแทนที่ด้วยเทมเพลตและคอนโทรลเลอร์ของตัวเอง

  • 🪟 ตัวยึดตำแหน่งเดี่ยว: มีองค์ประกอบหนึ่งที่มีเครื่องหมาย ng-view อยู่ ซึ่งจะแทรกเทมเพลตที่ถูกกำหนดเส้นทางไว้ทุกอัน และอนุญาตให้มีองค์ประกอบดังกล่าวเพียงหนึ่งเดียวต่อหน้าเท่านั้น
  • 🔗 การจับคู่เส้นทาง: แต่ละเส้นทางจะระบุ templateUrl และ controller เพื่อเชื่อมโยงมาร์กอัปและตรรกะเข้าด้วยกันสำหรับมุมมองนั้น
  • 📦 การพึ่งพาโมดูล: การแสดงผลต้องใช้ไฟล์ angular-route.js และการประกาศ dependency ของโมดูล ngRoute ด้วย
  • 🎯 มุมมองเริ่มต้น: เงื่อนไข otherwise จะเปลี่ยนเส้นทางไปยังที่อยู่ที่ไม่ตรงกัน ซึ่งเป็นสิ่งที่ทำให้แสดงผลในครั้งแรกที่โหลดหน้าเว็บ
  • 🌐 ต้องใช้เซิร์ฟเวอร์: เทมเพลตจะถูกดึงมาผ่านทาง HTTP ดังนั้นจึงต้องแสดงหน้าเว็บแทนที่จะเปิดจากระบบไฟล์
  • ⚠️ สถานะการสนับสนุน: AngularJS สิ้นสุดการสนับสนุนเมื่อวันที่ 31 ธันวาคม 2021 และจะไม่ได้รับการแก้ไขช่องโหว่ด้านความปลอดภัยอีกต่อไป

ไดเร็กทีฟ ng-view ของ AngularJS

เว็บไซต์ที่มีชื่อเสียง เช่น Gmail ใช้แนวคิดของแอปพลิเคชันหน้าเดียว (Single Page Application) เมื่อผู้ใช้ร้องขอหน้าเว็บอื่น แอปพลิเคชันจะไม่เปลี่ยนไปยังหน้าอื่น แต่จะแสดงมุมมองของหน้าใหม่ภายในหน้าเดิม ทำให้ผู้ใช้รู้สึกเหมือนไม่ได้ออกจากหน้าเดิมเลย AngularJS ก็ทำเช่นเดียวกันได้โดยใช้มุมมอง (views) ร่วมกับเส้นทาง (routes)

⚠️ ประกาศเกี่ยวกับการสนับสนุน: AngularJS มาถึงแล้ว สิ้นสุดชีวิตเมื่อวันที่ 31 ธันวาคม 2021 และจะไม่ได้รับการแก้ไขเพิ่มเติมหรือการแก้ไขด้านความปลอดภัยอีกต่อไป คำสั่งด้านล่างนี้ยังคงถูกต้องสำหรับการบำรุงรักษาแอปพลิเคชัน AngularJS 1.x ที่มีอยู่ ในระบบสมัยใหม่ เชิงมุม สิ่งที่เทียบเท่าคือ <router-outlet>.

มุมมองคืออะไร?

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

การรวมมุมมองและเส้นทางจะแบ่งแอปพลิเคชันออกเป็นมุมมองเชิงตรรกะและเชื่อมโยงแต่ละมุมมองเข้ากับเส้นทาง ตัวควบคุมซึ่งทำให้การใช้งานแอปพลิเคชันง่ายขึ้น

สมมติว่าเรามีแอปพลิเคชันสั่งซื้อสินค้าที่ลูกค้าสามารถดูรายการสั่งซื้อและสั่งซื้อสินค้าใหม่ได้ แผนภาพด้านล่างแสดงวิธีการแปลงแอปพลิเคชันนี้ให้เป็นแอปพลิเคชันหน้าเดียว

มุมมองคืออะไร

แทนที่จะใช้สองหน้าเว็บแยกกัน หน้าหนึ่งสำหรับ "ดูคำสั่งซื้อ" และอีกหน้าหนึ่งสำหรับ "สั่งซื้อใหม่" AngularJS ใช้การแสดงผลสองแบบในหน้าเดียวกัน โดยเข้าถึงได้ผ่านลิงก์อ้างอิงสองลิงก์ #show และ #new:

  • การนำทางไปยัง MyApp/#show แสดงมุมมอง "ดูคำสั่งซื้อ" โดยไม่ต้องออกจากหน้าเว็บ เฉพาะส่วนนั้นของหน้าเว็บปัจจุบันเท่านั้นที่จะรีเฟรช
  • การนำทางไปยัง MyApp/#new ทำเช่นเดียวกันสำหรับมุมมองคำสั่งซื้อใหม่

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

คำสั่ง ng-view ใน AngularJS

การขอ ngView คำสั่ง เติมเต็ม $route ให้บริการโดยการรวมเทมเพลตที่แสดงผลของเส้นทางปัจจุบันเข้าไปในไฟล์เลย์เอาต์หลัก โดยปกติแล้ว index.html.

ทุกครั้งที่เส้นทางปัจจุบันเปลี่ยนแปลง มุมมองที่แสดงก็จะเปลี่ยนแปลงตามไปด้วย $route ตั้งค่าโดยไม่ต้องโหลดหน้าเว็บใหม่ เส้นทาง ซึ่งแต่ละหัวข้อจะกล่าวถึงแยกกัน ในที่นี้จะเน้นที่การเพิ่มมุมมองหลายแบบ

ผังงานด้านล่างแสดงกระบวนการทั้งหมด ซึ่งตัวอย่างจะอธิบายทีละขั้นตอน

คำสั่ง ng-view ใน AngularJS

วิธีการใช้ ng-view ใน AngularJS

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

ขั้นตอน 1) รวมไฟล์ angular-route เป็นการอ้างอิงสคริปต์ ไฟล์นี้จำเป็นสำหรับการใช้งานเส้นทางและมุมมองหลายรายการ และสามารถดาวน์โหลดได้จากเว็บไซต์ AngularJS

รวมไฟล์ angular-route เข้าไปด้วย

ขั้นตอน 2) เพิ่มแท็ก href และแท็ก div

  1. เพิ่มแท็ก href ที่เชื่อมโยงไปยัง “เพิ่มกิจกรรมใหม่” และ “แสดงกิจกรรม”
  2. เพิ่ม div ที่มีเนื้อหาดังกล่าว ng-view คำสั่งสำหรับกำหนดขอบเขตการแสดงผล เมื่อใดก็ตามที่มีการคลิกลิงก์ใดลิงก์หนึ่ง การแสดงผลที่ตรงกันจะถูกแทรกเข้าไปในบริเวณนั้น

เพิ่มแท็ก href และแท็ก div

ขั้นตอน 3) ในแท็กสคริปต์ของ AngularJS ให้เพิ่มการตั้งค่าการกำหนดเส้นทาง (routing configuration)

  1. เมื่อผู้ใช้คลิก กิจกรรมใหม่ ลิงก์, โหลด AngularJS add_event.htmlแทรกมาร์กอัปเข้าไปในมุมมอง และใช้ AddEventController สำหรับตรรกะทางธุรกิจ
  2. เมื่อผู้ใช้คลิก เหตุการณ์แสดงผล ลิงก์กำลังโหลด show_event.html และการใช้งาน ShowDisplayController.
  3. การขอ otherwise เงื่อนไขนี้กำหนดมุมมองเริ่มต้นที่จะแสดงต่อผู้ใช้ ซึ่งในที่นี้คือ DisplayEvent

การกำหนดค่าเส้นทาง

ขั้นตอน 4) เพิ่มคอนโทรลเลอร์เพื่อประมวลผลตรรกะทางธุรกิจสำหรับทั้งสองฟังก์ชัน โดยแต่ละคอนโทรลเลอร์จะตั้งค่าข้อความบนอ็อบเจ็กต์ขอบเขตของตน ซึ่งจะแสดงขึ้นเมื่อวิวที่ตรงกันปรากฏขึ้น

เพิ่มตัวควบคุม

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
    <script src="https://code.angularjs.org/1.8.3/angular.min.js"></script>
    <script src="https://code.angularjs.org/1.8.3/angular-route.js"></script>
</head>
<body ng-app="sampleApp">

<h1>Guru99 Global Event</h1>

<div class="container">
    <ul>
        <li><a href="#!/NewEvent">Add New Event</a></li>
        <li><a href="#!/DisplayEvent">Display Event</a></li>
    </ul>
    <div ng-view></div>
</div>

<script>
    var app = angular.module('sampleApp', ["ngRoute"]);

    app.config(function($routeProvider) {
        $routeProvider
            .when("/NewEvent", {
                templateUrl: "add_event.html",
                controller: "AddEventController"
            })
            .when("/DisplayEvent", {
                templateUrl: "show_event.html",
                controller: "ShowDisplayController"
            })
            .otherwise({
                redirectTo: '/DisplayEvent'
            });
    });

    app.controller("AddEventController", function($scope) {
        $scope.message = "This is to Add a new Event";
    });

    app.controller("ShowDisplayController", function($scope) {
        $scope.message = "This is to display an Event";
    });
</script>

</body>
</html>

⚠️ มีการแก้ไขข้อมูลในรายการเดิม 3 จุด ประการแรก ลิงก์เหล่านี้อ่านได้ดังนี้ #!NewEvent โดยไม่มีเครื่องหมายทับในขณะที่เส้นทางถูกประกาศไว้ /NewEventดังนั้นจึงไม่มีอะไรตรงกัน ตั้งแต่ AngularJS เวอร์ชัน 1.6 เป็นต้นไป คำนำหน้าแฮชเริ่มต้นคือ !ซึ่งทำให้ได้ที่อยู่ที่ถูกต้อง #!/NewEvent — มีเครื่องหมายทับหลังเครื่องหมายอัศเจรีย์ ประการที่สอง ShowDisplayController ตั้งค่าข้อความเป็น “นี่คือการแสดงเหตุการณ์” โดยตัดคำบางคำออก ไปยัง ประการที่สาม คือ ข้อความโดยรอบที่ยกมาอ้างอิง lib/bootstrap.js ถูกโหลดจากพาธสัมพัทธ์ที่ไม่สามารถระบุตำแหน่งได้และไม่เคยถูกใช้งาน ดังนั้นจึงถูกลบออกไปแล้ว

ขั้นตอน 5) สร้างหน้าเว็บ add_event.html และ show_event.htmlแต่ละส่วนจะมีส่วนหัวและส่วนแสดงข้อความที่ได้รับมาจากตัวควบคุม

  • add_event.html

add_event.html

<h2>Add New Event</h2>

{{message}}
  • show_event.html

show_event.html

<h2>Show Event</h2>

{{message}}

หากโค้ดทำงานสำเร็จ ผลลัพธ์ต่อไปนี้จะปรากฏในเบราว์เซอร์

Output:

เอาต์พุต ng-view

เอาต์พุต ng-view

ข้อผิดพลาดทั่วไปของ ng-view และวิธีแก้ไข

เกือบทุกกรณีที่ ng-view ล้มเหลว มักเกิดจากวิธีการเชื่อมต่อโมดูล รูปแบบที่อยู่ หรือวิธีการแสดงผลหน้าเว็บ มากกว่าตัวคำสั่งเอง

  • พื้นที่แสดงผลยังคงว่างเปล่า: ngRoute โมดูลไม่ได้ถูกระบุว่าเป็นส่วนประกอบที่จำเป็น หรือ angular-route.js ไม่ได้โหลด ทั้งสองอย่างจำเป็นต้องมี และสคริปต์ต้องมาทีหลัง angular.min.js.
  • ลิงก์เปลี่ยนที่อยู่ แต่ไม่มีอะไรแสดงผล: href ไม่ตรงกับเส้นทาง ตั้งแต่ AngularJS เวอร์ชัน 1.6 เป็นต้นไป ที่อยู่ต้องเป็นไปตามนี้ #!/Routeโค้ดเก่าที่เขียนขึ้นสำหรับเวอร์ชัน 1.5 ถูกนำมาใช้ #/Route.
  • ไม่สามารถโหลดเทมเพลตได้เนื่องจากเกิดข้อผิดพลาด CORS: หน้าเว็บถูกเปิดโดยตรงจากดิสก์ ควรให้บริการผ่าน HTTP เพราะว่า templateUrl ไฟล์ดังกล่าวถูกดึงข้อมูลโดยคำขอ AJAX และโปรโตคอลไฟล์จะถูกบล็อก
  • มีเพียงมุมมองสุดท้ายเท่านั้นที่จะปรากฏ: หากมีองค์ประกอบมากกว่าหนึ่งรายการที่ใช้ ng-view นั้น AngularJS จะอนุญาตให้มีพื้นที่แสดงผลเพียงพื้นที่เดียวต่อหน้า
  • เมื่อโหลดครั้งแรกจะไม่แสดงอะไรเลย: ไม่ otherwise มีการกำหนดค่าเงื่อนไขไว้แล้ว ดังนั้นที่อยู่ว่างเปล่าจึงไม่ตรงกับเส้นทางใดๆ

คำถามที่พบบ่อย

ไม่ ngRoute รองรับพื้นที่แสดงผลเพียงพื้นที่เดียวต่อหน้า หากต้องการพื้นที่แสดงผลที่มีชื่อหลายพื้นที่พร้อมกัน ให้ใช้ไลบรารี ui-router ซึ่งมี ui-view และรองรับการแสดงผลแบบซ้อนกันและการแสดงผลแบบพี่น้อง

เปิดใช้งานโหมด HTML5 ด้วย $locationProvider.html5Mode(true) และเพิ่มแท็ก base จากนั้นเซิร์ฟเวอร์จะต้องเขียนเส้นทางที่ไม่รู้จักใหม่เป็น index.html มิฉะนั้นการรีเฟรชจะแสดงข้อผิดพลาด 404

ส่วนใหญ่แล้ว AI เครื่องมือเหล่านี้จะแปลงตารางเส้นทางเป็นอาร์เรย์ Angular Routes และเปลี่ยน ng-view เป็น router-outlet ส่วนคอนโทรลเลอร์ยังคงต้องเขียนใหม่เป็นคอมโพเนนต์ด้วยตนเอง

ผู้ช่วย AI ตรวจสอบสาเหตุหลักสามประการได้อย่างรวดเร็ว ได้แก่ การขาดส่วนประกอบ ngRoute, คำนำหน้าแฮชที่ไม่ตรงกับเส้นทาง และเส้นทางเทมเพลตที่เบราว์เซอร์ไม่สามารถดึงข้อมูลได้

ใช่ เพิ่ม resolve บล็อกไปยังเส้นทางนั้น AngularJS จะรอให้ Promise เหล่านั้นเสร็จสมบูรณ์ก่อนที่จะสร้างอินสแตนซ์ของคอนโทรลเลอร์ ซึ่งจะช่วยป้องกันไม่ให้หน้าจอว่างเปล่าขณะที่ข้อมูลกำลังเข้ามา

สรุปโพสต์นี้ด้วย: