การกำหนดเส้นทางด้วยพารามิเตอร์ใน AngularJs

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

การกำหนดเส้นทางใน AngularJS เปลี่ยนหน้า HTML หน้าเดียวให้กลายเป็นแอปพลิเคชันที่มีหลายมุมมองโดยใช้แผนที่ping URL แปลงส่วนย่อยเป็นเทมเพลตและคอนโทรลเลอร์ โมดูล ngRoute และบริการ $routeProvider กำหนดการแมปเหล่านี้pingในขณะที่คำสั่ง ng-view จะแทรกเทมเพลตที่ตรงกันเข้าไป

  • 🧩 กลไกหลัก: $routeProvider จะจับคู่กับ fragment ที่อยู่หลังสัญลักษณ์ # และโหลด templateUrl และ controller ที่จับคู่กันลงใน ng-view
  • 📦 ส่วนประกอบที่จำเป็น: การกำหนดเส้นทางนั้นอยู่นอกไลบรารีหลัก ดังนั้นจึงต้องอ้างอิงถึงไฟล์ angular-route.js และประกาศ ngRoute ในโมดูลนั้น
  • 🎯 เส้นทางเริ่มต้น: บล็อก otherwise จะเปลี่ยนเส้นทางไปยังเส้นทางที่ไม่ตรงกัน เพื่อป้องกันไม่ให้แสดงหน้าจอว่างเปล่าเมื่อแอปพลิเคชันโหลดครั้งแรก
  • 🔢 พารามิเตอร์เส้นทาง: เครื่องหมายโคลอน เช่น :topicId จะจับค่าต่างๆ URL ส่วนต่างๆ ที่ตัวควบคุมอ่านผ่านตัวแปร $routeParams
  • การโหลดข้อมูลล่วงหน้า: คุณสมบัติ resolve จะทำการดึงข้อมูลเสร็จสิ้นก่อนที่คอนโทรลเลอร์จะทำงาน ดังนั้นวิวจะไม่แสดงผลในสถานะว่างเปล่า
  • 🔗 ทำความสะอาด URLs: การตั้งค่า html5Mode บน $locationProvider จะลบแฮชออก แต่เซิร์ฟเวอร์จะต้องเขียนเส้นทางที่ไม่รู้จักใหม่ไปยังหน้าหลัก

การกำหนดเส้นทาง AngularJS พร้อมพารามิเตอร์

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

แอปพลิเคชันหน้าเดียวคืออะไร

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

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

การกำหนดเส้นทางใน AngularJS คืออะไร

การกำหนดเส้นทางใน AngularJS เป็นวิธีการที่ช่วยให้คุณสร้างแอปพลิเคชันหน้าเดียว (Single Page Application) ได้ โดยจะช่วยให้คุณสร้างสิ่งต่างๆ ได้หลากหลาย URLการกำหนดเส้นทาง (routing) ใน AngularJS ช่วยให้แสดงเนื้อหาได้หลากหลายขึ้นอยู่กับเส้นทางที่เลือก โดยจะระบุไว้ในไฟล์ .ng/ ... URL หลังเครื่องหมาย #

ลองยกตัวอย่างเว็บไซต์ที่โฮสต์ผ่านทาง... URL http://example.com/index.html.

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

สัญลักษณ์ # จะถูกใช้พร้อมกับเส้นทางที่แตกต่างกัน (ShowEvent, DisplayEvent และ DeleteEvent)

  • หากต้องการดูเหตุการณ์ทั้งหมด ผู้ใช้จะถูกนำไปยัง http://example.com/index.html#ShowEvent
  • หากต้องการชมเหตุการณ์ใดเหตุการณ์หนึ่งโดยเฉพาะ พวกเขาจะถูกแนะนำให้ไปที่... http://example.com/index.html#DisplayEvent
  • หากต้องการลบกิจกรรม พวกเขาจะถูกนำไปยัง... http://example.com/index.html#DeleteEvent

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

การเพิ่มเส้นทาง AngularJS โดยใช้ $routeProvider

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

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

  1. อ้างอิงถึงไฟล์ angular-route.js นี้ Javaต้นฉบับ ไฟล์ที่พัฒนาโดย Googleประกอบด้วยฟังก์ชันการกำหนดเส้นทางทั้งหมด และต้องรวมไว้เพื่อให้แอปพลิเคชันสามารถอ้างอิงถึงความต้องการการกำหนดเส้นทางของโมดูลได้
  2. เพิ่ม dependency ไปยังโมดูล ngRoute จากภายในแอปพลิเคชันของคุณ หากไม่มี dependency นี้ จะไม่สามารถใช้งานการกำหนดเส้นทาง (routing) ในแอปพลิเคชัน AngularJS ได้เลย

ด้านล่างนี้คือไวยากรณ์ทั่วไปของคำสั่งนี้ นี่เป็นเพียงการประกาศปกติของโมดูลที่มีการรวมคีย์เวิร์ด ngRoute

var module = angular.module("sampleApp", ['ngRoute']);
  1. กำหนดค่าตัวแปร `$routeProvider` ของคุณ ตัวแปรนี้จะกำหนดเส้นทางต่างๆ ในแอปพลิเคชันของคุณ โดยไวยากรณ์จะระบุว่า เมื่อเลือกเส้นทางที่เกี่ยวข้องแล้ว ให้ใช้เส้นทางนั้นในการแสดงผลมุมมองที่กำหนด
when(path, route)
  1. ลิงก์ไปยังเส้นทางของคุณจากภายในหน้า HTML ของคุณ ในหน้า HTML คุณจะเพิ่มลิงก์อ้างอิงไปยังเส้นทางต่างๆ ที่มีอยู่ในแอปพลิเคชันของคุณ
<a href="#!/route1">Route 1</a><br/>
  1. ในที่สุดก็จะรวมของ คำสั่ง ng-viewซึ่งโดยปกติจะอยู่ในแท็ก div สิ่งนี้จะถูกใช้เพื่อแทรกเนื้อหาของมุมมองเมื่อเลือกเส้นทางที่เกี่ยวข้อง

💡 เคล็ดลับ: ทั้งห้าขั้นตอนเป็นขั้นตอนบังคับ สาเหตุที่พบบ่อยที่สุดที่ทำให้เส้นทาง (route) ไม่ทำงานโดยไม่มีการแจ้งเตือนใดๆ คือการขาดการอ้างอิง angular-route.js เนื่องจาก $routeProvider จะไม่มีอยู่หากไม่มีการอ้างอิงดังกล่าว ส่วนถัดไปจะนำทั้งห้าขั้นตอนมารวมกันในตัวอย่างการทำงาน

ตัวอย่างการกำหนดเส้นทาง AngularJS

ตอนนี้เรามาดูตัวอย่างการกำหนดเส้นทางโดยใช้ขั้นตอนที่กล่าวมาข้างต้น

ในตัวอย่างการกำหนดเส้นทาง AngularJS ของเราพร้อมพารามิเตอร์

  • ลิงก์หนึ่งใช้สำหรับแสดงหัวข้อต่างๆ AngularJS แน่นอนและอีกอันหนึ่งมีไว้สำหรับ Node.js หลักสูตร
  • เมื่อผู้ใช้คลิกลิงก์ใดลิงก์หนึ่ง หัวข้อสำหรับหลักสูตรนั้นจะปรากฏขึ้น

ขั้นตอน 1) รวมไฟล์เชิงมุมเป็นการอ้างอิงสคริปต์

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

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

ขั้นตอน 2) เพิ่มแท็ก href ซึ่งจะแสดงลิงก์ไปยัง “หัวข้อ JS เชิงมุม” และ “หัวข้อ JS ของโหนด”

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

ขั้นตอน 3) เพิ่มแท็ก div ด้วยคำสั่ง ng-view ซึ่งจะแสดงมุมมอง

สิ่งนี้จะช่วยให้สามารถแทรกมุมมองที่เกี่ยวข้องเมื่อใดก็ตามที่ผู้ใช้คลิกที่ "หัวข้อ Angular JS" หรือ "หัวข้อ Node JS"

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

ขั้นตอน 4) ในแท็กสคริปต์ของคุณสำหรับ AngularJS ให้เพิ่ม “โมดูล ngRoute” และบริการ “$routeProvider”

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

Code คำอธิบาย:

  1. ติดตั้งโมดูล “ngRoute” เมื่อติดตั้งโมดูลนี้แล้ว Angular จะจัดการการกำหนดเส้นทางโดยอัตโนมัติและเข้าใจคำสั่งการกำหนดเส้นทางทั้งหมด
  2. $routeProvider เป็นบริการที่คอยรับฟังเส้นทางที่ถูกเรียกใช้ในเบื้องหลัง เมื่อผู้ใช้คลิกลิงก์ บริการนี้จะตรวจจับได้และตัดสินใจว่าจะใช้เส้นทางใด
  3. สร้างเส้นทางเดียวสำหรับลิงก์ Angular: เมื่อคลิกแล้ว ให้แทรก Angular.html และใช้ 'AngularController' สำหรับตรรกะทางธุรกิจ
  4. สร้างเส้นทางหนึ่งเส้นสำหรับลิงก์ Node ซึ่งจะแทรกไฟล์ Node.html และใช้งาน 'NodeController' ในลักษณะเดียวกัน

ขั้นตอน 5) ถัดไปคือการเพิ่มตัวควบคุมเพื่อประมวลผลตรรกะทางธุรกิจสำหรับทั้ง AngularController และ NodeController

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

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

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Event Registration</title>
</head>
<body ng-app="sampleApp">

<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>

<h1> Guru99 Global Event</h1>

<div class="container">
<ul>
<li><a href="#!/Angular">Angular JS Topics</a></li>
<li><a href="#!/Node">Node JS Topics</a></li>
</ul>
<div ng-view></div>
</div>

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

sampleApp.config(['$routeProvider',
function($routeProvider) {
  $routeProvider.
  when('/Angular', {
    templateUrl: 'Angular.html',
    controller: 'AngularController'
  }).
  when('/Node', {
    templateUrl: 'Node.html',
    controller: 'NodeController'
  });
}]);

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"}
  ];
});

// NodeController follows the same shape with Node.js topics
sampleApp.controller('NodeController', function($scope) {
  $scope.tutorial = [{Name: "Promises", Description: "Power of Promises"}];
});
</script>
</body>
</html>

⚠️ มีการแก้ไขแล้ว การขอ <title> ป้ายติดอยู่ข้างใน <body>, chrset="UTF 8" สะกดผิด ลิงก์ที่สองชี้ไปที่ #Node.html แทนที่จะใช้เส้นทางที่ลงทะเบียนไว้ /Nodeและเส้นทางเทมเพลตจะมีเครื่องหมายทับนำหน้าซึ่งจะแยกออกมาจากรากของโดเมน

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

ขั้นตอน 6) สร้างเพจชื่อ Angular.html และ Node.html สำหรับแต่ละหน้า เรากำลังดำเนินการตามขั้นตอนด้านล่าง

ขั้นตอนเหล่านี้จะทำให้แน่ใจว่าคู่คีย์-ค่าทั้งหมดของอาร์เรย์จะแสดงในแต่ละหน้า

  1. การใช้ คำสั่ง ng-ซ้ำ เพื่อวนไปทีละคู่คีย์-ค่าที่กำหนดไว้ในตัวแปรของบทเรียน
  2. การแสดงชื่อและคำอธิบายของคู่คีย์-ค่าแต่ละคู่
  • Angular.html
<h2>Angular</h2>
<ul ng-repeat="ptutor in tutorial">
<li>Course : {{ptutor.Name}} - {{ptutor.Description}}</li>
</ul>
  • โหนด.html — เหมือนกับรายการด้านบนทุกประการ เพียงแต่เปลี่ยนหัวข้อเป็น “โหนด” ทั้งสองแม่แบบอ่านได้เหมือนกัน tutorial ตัวแปร ซึ่งตัวควบคุมแต่ละตัวจะส่งมาจากขอบเขตของตนเอง

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

⚠️ การแก้ไข: หัวข้อในไฟล์ Angular.html เดิมเขียนว่า “Anguler” การสะกดคำถูกต้องแล้วด้านบน

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

Output:

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

หากคุณคลิกที่ลิงก์ AngularJS Topics จะแสดงผลลัพธ์ดังต่อไปนี้

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

ผลลัพธ์แสดงให้เห็นชัดเจนว่า

  • เมื่อคลิกลิงก์ “หัวข้อ JS เชิงมุม” ผู้ให้บริการเส้นทางที่เราประกาศในโค้ดของเราตัดสินใจว่าควรแทรกโค้ด Angular.html
  • โค้ดนี้จะถูกแทรกลงในแท็ก “div” ซึ่งมีคำสั่ง ng-view นอกจากนี้ เนื้อหาสำหรับคำอธิบายหลักสูตรยังมาจาก “ตัวแปรการสอน” ซึ่งเป็นส่วนหนึ่งของวัตถุขอบเขตที่กำหนดใน AngularController
  • เมื่อมีผู้คลิกที่ Node.js หัวข้อ ผลลัพธ์เดียวกันจะเกิดขึ้น และมุมมองของหัวข้อ Node.js จะปรากฏขึ้น
  • นอกจากนี้ โปรดสังเกตว่าหน้าเว็บ URL ยังคงเหมือนเดิม มีเพียงเส้นทางหลังแท็ก # เท่านั้นที่เปลี่ยนแปลง และนี่คือแนวคิดของแอปพลิเคชันหน้าเดียว แท็ก #hash ใน URL เป็นตัวคั่นระหว่างเส้นทาง (ซึ่งในกรณีของเราคือ 'Angular') และหน้า HTML หลัก (Sample.html)

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

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

การสร้างเส้นทางเริ่มต้นใน AngularJS

การกำหนดเส้นทางใน AngularJS ยังอำนวยความสะดวกในการมีเส้นทางเริ่มต้น นี่คือเส้นทางที่ถูกเลือกหากไม่มีการจับคู่กับเส้นทางที่มีอยู่

เส้นทางเริ่มต้นจะถูกสร้างขึ้นโดยการเพิ่มเงื่อนไขต่อไปนี้เมื่อกำหนดบริการ $routeProvider

ไวยากรณ์ด้านล่างนี้หมายถึงการเปลี่ยนเส้นทางไปยังหน้าอื่นหากเส้นทางที่มีอยู่ไม่ตรงกัน

otherwise({
  redirectTo: 'page'
});

ลองใช้ตัวอย่างเดียวกันข้างต้นและเพิ่มเส้นทางเริ่มต้นให้กับบริการ $routeProvider ของเรา

การสร้างเส้นทางเริ่มต้นใน AngularJS

sampleApp.config(['$routeProvider',
function($routeProvider) {
  $routeProvider.
  when('/Angular', {
    templateUrl: 'Angular.html',
    controller: 'AngularController'
  }).
  when('/Node', {
    templateUrl: 'Node.html',
    controller: 'NodeController'
  }).
  otherwise({
    redirectTo: '/Angular'
  });
}]);

Code คำอธิบาย:

  1. ต่อไปนี้เราใช้โค้ดเดียวกันกับด้านบน โดยมีข้อแตกต่างเพียงอย่างเดียวคือ เราใช้คำสั่ง otherwise และตัวเลือก “redirectTo” เพื่อระบุว่าควรโหลดวิวใดหากไม่มีการระบุเส้นทาง ในกรณีของเรา เราต้องการให้แสดงวิว '/Angular'

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

Output:

การสร้างเส้นทางเริ่มต้นใน AngularJS

จากผลลัพธ์ที่ได้

  • คุณจะเห็นได้อย่างชัดเจนว่ามุมมองเริ่มต้นที่แสดงคือมุมมองของ AngularJS
  • เนื่องจากเมื่อโหลดหน้าเพจ มันจะไปที่ตัวเลือก 'otherwise' ในฟังก์ชัน $routeProvider และโหลดมุมมอง '/Angular'

เส้นทางเริ่มต้นจะเป็นตัวกำหนดว่ามุมมองใดจะถูกโหลด ส่วนถัดไปจะกล่าวถึงวิธีการที่เส้นทางเดียวสามารถให้บริการข้อมูลได้หลายรายการโดยการส่งค่าเข้าไปใน URL.

วิธีการเข้าถึงพารามิเตอร์จากเส้นทาง AngularJS

Angular ยังมีฟังก์ชันการส่งพารามิเตอร์ระหว่างการกำหนดเส้นทางด้วย โดยพารามิเตอร์จะถูกเพิ่มเข้าไปที่ส่วนท้ายของเส้นทาง URL, ตัวอย่างเช่น, http://guru99/index.html#/Angular/1- ในตัวอย่างการกำหนดเส้นทางเชิงมุมนี้

  1. http://guru99/index.html เป็นแอปพลิเคชันหลักของเรา URL
  2. สัญลักษณ์ # เป็นตัวคั่นระหว่างแอปพลิเคชันหลัก URL และเส้นทาง
  3. เชิงมุมคือเส้นทางของเรา
  4. และสุดท้าย '1' คือพารามิเตอร์ที่ถูกเพิ่มเข้าไปในเส้นทางของเรา

ไวยากรณ์ทั่วไปคือ HTMLPage#/เส้นทาง/พารามิเตอร์ดังนั้นหัวข้อก่อนหน้านี้จึงกลายเป็น Sample.html#/Angular/1, #/Angular/2 และ #/Angular/3 โดยที่ตัวเลขคือ topicid

เรามาดูรายละเอียดกันว่าเราจะสร้างเส้นทาง (route) ใน Angular โดยมีพารามิเตอร์ได้อย่างไร

ขั้นตอนที่ 1) เพิ่มโค้ดต่อไปนี้ลงในมุมมองของคุณ

  1. เพิ่มตารางเพื่อแสดงหัวข้อทั้งหมดของหลักสูตร Angular JS ให้ผู้ใช้เห็น
  2. เพิ่มแถวในตารางเพื่อแสดงหัวข้อ “ตัวควบคุม” สำหรับแถวนี้ ให้ตั้งค่า href เป็น “#!/Angular/1” เพื่อให้เมื่อคลิกที่หัวข้อ จะส่งพารามิเตอร์ 1 เข้าไป URL พร้อมกับเส้นทางนั้น ๆ
  3. เพิ่มแถวสำหรับหัวข้อ “Models” โดยตั้งค่า href เป็น “#!/Angular/2” เพื่อให้พารามิเตอร์ที่ 2 เคลื่อนที่ไปตามแถวนั้น URL.
  4. เพิ่มแถวสำหรับหัวข้อ “Directives” โดยตั้งค่า href เป็น “#!/Angular/3” เพื่อให้พารามิเตอร์ที่ 3 เดินทางไปในแถวนั้น URL.

เข้าถึงพารามิเตอร์จากเส้นทาง AngularJS

ขั้นตอนที่ 2) เพิ่ม topic id ในฟังก์ชันบริการ routeProvider
ในฟังก์ชันบริการ routeProvider ให้เพิ่ม :topicId ตัวยึดตำแหน่งเพื่อระบุว่าพารามิเตอร์ใด ๆ ที่ส่งผ่านเข้ามา URL หลังจากนั้นควรกำหนดเส้นทางให้กับตัวแปร topicId

เข้าถึงพารามิเตอร์จากเส้นทาง AngularJS

ขั้นตอนที่ 3) เพิ่มรหัสที่จำเป็นลงในคอนโทรลเลอร์

  1. โปรดตรวจสอบให้แน่ใจว่าได้เพิ่ม “$routeParams” เป็นพารามิเตอร์ก่อนเมื่อกำหนดฟังก์ชันคอนโทรลเลอร์ พารามิเตอร์นี้จะสามารถเข้าถึงพารามิเตอร์เส้นทางทั้งหมดที่ส่งเข้ามาได้ URL.
  2. “$routeParams” เก็บค่า topicId ที่ส่งมาในเส้นทาง กำลังแนบ $routeParams.topicId ตามขอบเขตที่กำหนด $scope.tutorialid ทำให้สามารถดูได้โดยใช้ tutorialid

เข้าถึงพารามิเตอร์จากเส้นทาง AngularJS

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Event Registration</title>
</head>
<body ng-app="sampleApp">

<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>

<h1> Guru99 Global Event</h1>
<table class="table table-striped">
<tbody>
<tr><td>1</td><td>Controllers</td>
<td><a href="#!/Angular/1">Topic details</a></td></tr>
<!-- rows 2 and 3 repeat with /Angular/2 and /Angular/3 -->
</tbody>
</table>
<div ng-view></div>

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

sampleApp.config(['$routeProvider',
function($routeProvider) {
  $routeProvider.
  when('/Angular/:topicId', {
    templateUrl: 'Angular.html',
    controller: 'AngularController'
  });
}]);

sampleApp.controller('AngularController', ['$scope', '$routeParams',
function($scope, $routeParams) {
  $scope.tutorialid = $routeParams.topicId;
}]);
</script>
</body>
</html>

⚠️ มีการแก้ไขแล้ว ต้นฉบับใช้ตัวอักษร l แทนที่จะเป็นตัวเลข 1 in href="#Angular/l"ละเว้น ng-view คอนเทนเนอร์ ดังนั้นเทมเพลตจึงไม่มีที่แสดงผล และโหลด angular-route.js ก่อน angular.min.jsซึ่งจะทำให้เกิดข้อผิดพลาดของโมดูล

ขั้นตอนที่ 4) เพิ่มนิพจน์เพื่อแสดงค่าตัวแปร
เพิ่มนิพจน์เพื่อแสดงตัวแปร Tutorialid ในหน้า Angular.html

เข้าถึงพารามิเตอร์จากเส้นทาง AngularJS

<h2>Angular</h2>

<br><br>{{tutorialid}}

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

Output:

เข้าถึงพารามิเตอร์จากเส้นทาง AngularJS

ในหน้าจอเอาต์พุต

  • หากคุณคลิกที่ลิงก์รายละเอียดหัวข้อสำหรับหัวข้อแรก เลข 1 จะถูกเพิ่มต่อท้าย URL.
  • ตัวเลขนั้นจะถูกนำมาใช้เป็นอาร์กิวเมนต์ "routeParams" และสามารถเข้าถึงได้ในคอนโทรลเลอร์

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

วิธีการโหลดข้อมูลล่วงหน้าด้วยคุณสมบัติ resolve

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

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

sampleApp.config(['$routeProvider',
function($routeProvider) {
  $routeProvider.
  when('/Angular/:topicId', {
    templateUrl: 'Angular.html',
    controller: 'AngularController',
    resolve: {
      // The router waits for this promise before rendering
      topic: ['$http', '$route', function($http, $route) {
        var id = $route.current.params.topicId;
        return $http.get('/api/topics/' + id).then(function(response) {
          return response.data;
        });
      }]
    }
  });
}]);

// 'topic' is injected already resolved, so no loading state is needed
sampleApp.controller('AngularController', ['$scope', 'topic',
function($scope, topic) {
  $scope.topic = topic;
}]);

มีพฤติกรรมสองอย่างที่สำคัญในที่นี้ การปฏิเสธคำสัญญาจะยกเลิกการเปลี่ยนแปลงเส้นทางและทำให้เบราว์เซอร์ยังคงอยู่ที่มุมมองปัจจุบัน ดังนั้นคำขอที่ล้มเหลวจะไม่ทำให้หน้าเว็บเสียหาย อย่างไรก็ตาม เนื่องจากเราเตอร์จะบล็อกในขณะที่คำสัญญาอยู่ในสถานะรอการดำเนินการ ปลายทางที่ทำงานช้าจะทำให้แอปพลิเคชันดูเหมือนหยุดทำงาน (Pair) resolve โดยมีตัวชี้วัดความคืบหน้าที่ขับเคลื่อนโดย $routeChangeStart และ $routeChangeSuccess เหตุการณ์ที่เกิดขึ้น

⚠️ คำเตือน: ห้ามวางการตรวจสอบความถูกต้องไว้เฉพาะภายในเท่านั้น resolveการปฏิเสธเส้นทางจะซ่อนมุมมอง แต่จะไม่ปกป้องข้อมูลที่อยู่เบื้องหลัง และปลายทาง API ยังคงต้องบังคับใช้การเข้าถึงบนเซิร์ฟเวอร์อยู่ดี

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

วิธีใช้บริการเส้นทาง $route เชิงมุม

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

myApp.controller('MyController', function($scope, $route) { ... });
  1. myApp คือโมดูล AngularJS ที่กำหนดไว้สำหรับแอปพลิเคชันของคุณ
  2. MyController คือชื่อของคอนโทรลเลอร์ที่กำหนดไว้สำหรับแอปพลิเคชันของคุณ
  3. เช่นเดียวกับที่ $scope ส่งต่อข้อมูลจากคอนโทรลเลอร์ไปยังวิว $route ก็แสดงคุณสมบัติของเส้นทางปัจจุบันเช่นกัน

มาดูกันว่าเราสามารถใช้บริการ $route ได้อย่างไร

ในตัวอย่างนี้

  • เราจะสร้างตัวแปรที่กำหนดเองอย่างง่ายที่เรียกว่า "mytext" ซึ่งจะมีสตริง "นี่คือเชิงมุม"
  • เราจะเพิ่มตัวแปรนี้เข้าไปในเส้นทางของเรา Later เราจะเข้าถึงสตริงนี้จากคอนโทรลเลอร์ของเราโดยใช้บริการ $route จากนั้นใช้ object scope เพื่อแสดงผลในวิวของเรา

เรามาดูขั้นตอนที่เราต้องทำเพื่อให้บรรลุเป้าหมายนี้กัน

ขั้นตอน 1) เพิ่มคู่คีย์-ค่าที่กำหนดเองให้กับเส้นทาง ที่นี่ เรากำลังเพิ่มคีย์ที่เรียกว่า 'mytext' และกำหนดค่าเป็น "นี่คือเชิงมุม"

บริการเส้นทาง $ เชิงมุม

ขั้นตอน 2) เพิ่มโค้ดที่เกี่ยวข้องลงในคอนโทรลเลอร์

  1. เพิ่มพารามิเตอร์ `$route` ลงในฟังก์ชันคอนโทรลเลอร์ พารามิเตอร์ `$route` เป็นพารามิเตอร์สำคัญที่กำหนดไว้ใน Angular ซึ่งช่วยให้สามารถเข้าถึงคุณสมบัติของเส้นทางได้
  2. ตัวแปร “mytext” ที่กำหนดไว้ในเส้นทางสามารถเข้าถึงได้ผ่านการอ้างอิง $route.current จากนั้นจะกำหนดให้กับตัวแปร 'ข้อความ' ของวัตถุขอบเขต ตัวแปรข้อความสามารถเข้าถึงได้จากมุมมองตามลำดับ

บริการเส้นทาง $ เชิงมุม

// Only the config and controller change; the page markup is unchanged
sampleApp.config(['$routeProvider',
function($routeProvider) {
  $routeProvider.
  when('/Angular/:topicId', {
    mytext: "This is angular",   // custom key attached to the route
    templateUrl: 'Angular.html',
    controller: 'AngularController'
  });
}]);

sampleApp.controller('AngularController', ['$scope', '$routeParams', '$route',
function($scope, $routeParams, $route) {
  $scope.tutorialid = $routeParams.topicId;
  $scope.text = $route.current.mytext;
}]);

ขั้นตอน 3) เพิ่มการอ้างอิงถึงตัวแปรข้อความจากวัตถุขอบเขตเป็นนิพจน์ สิ่งนี้จะถูกเพิ่มลงในหน้า Angular.html ของเราดังที่แสดงด้านล่าง

ซึ่งจะทำให้ข้อความ "นี่คือเชิงมุม" ถูกแทรกเข้าไปในมุมมอง นิพจน์ {{tutorialid}} เหมือนกับที่เห็นในหัวข้อที่แล้ว และจะแสดงตัวเลข '1'

บริการเส้นทาง $ เชิงมุม

<h2>Angular</h2>

<br><br>{{text}}
<br><br>{{tutorialid}}

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

Output:

บริการเส้นทาง $ เชิงมุม

จากผลลัพธ์ที่ได้

  • เราจะเห็นว่าข้อความ "This is angular" จะปรากฏขึ้นเมื่อเราคลิกลิงก์ใดๆ ในตาราง นอกจากนี้ ID หัวข้อยังจะปรากฏขึ้นพร้อมกันกับข้อความด้วย

ทุกๆ URL ส่วนที่แสดงอยู่นี้ยังคงมีสัญลักษณ์ # อยู่ ขั้นตอนการตั้งค่าขั้นสุดท้ายจะลบสัญลักษณ์นี้ออก

การเปิดใช้งานการกำหนดเส้นทาง HTML5

การกำหนดเส้นทาง HTML5 ถูกนำมาใช้เพื่อสร้างโครงสร้างที่สะอาดตา URLหมายความว่า การลบแฮชแท็กออกจาก URLดังนั้นการกำหนดเส้นทาง URLเมื่อใช้การกำหนดเส้นทาง HTML5 จะปรากฏดังที่แสดงด้านล่าง

ตัวอย่าง.html/Angular/1

ตัวอย่าง.html/Angular/2

ตัวอย่าง.html/Angular/3

แนวคิดนี้โดยทั่วไปรู้จักกันในชื่อการนำเสนอที่สวยงาม URL ให้กับผู้ใช้

มี 2 ​​ขั้นตอนหลักที่ต้องดำเนินการสำหรับการกำหนดเส้นทาง HTML5

  1. การกำหนดค่า $locationProvider
  2. การตั้งค่าฐานของเราสำหรับลิงค์ที่เกี่ยวข้อง

เรามาดูรายละเอียดวิธีการดำเนินการตามขั้นตอนต่างๆ ในตัวอย่างของเรากัน

ขั้นตอน 1) เพิ่มโค้ดที่เกี่ยวข้องลงในโมดูล Angular

  1. เพิ่ม <base> เพิ่มแท็ก <head> ลงในส่วนหัวของเอกสาร สิ่งนี้จำเป็นสำหรับการกำหนดเส้นทางใน HTML5 เพื่อให้แอปพลิเคชันทราบตำแหน่งฐานของแอปพลิเคชัน
  2. เพิ่มบริการ `$locationProvider` บริการนี้ช่วยให้คุณกำหนด `html5Mode` ได้
  3. ตั้งค่า html5Mode ของบริการ $locationProvider เป็นจริง

การเปิดใช้งานการกำหนดเส้นทาง HTML5

ขั้นตอน 2) ลบแท็ก # ทั้งหมดออกจากลิงก์ ('Angular/1', 'Angular/2', 'Angular/3') เพื่อให้อ่านง่ายขึ้น URLs.

การเปิดใช้งานการกำหนดเส้นทาง HTML5

<!-- In the head: required by html5Mode so relative templates resolve -->
<base href="/">

<!-- In the body: the # is dropped from every link -->
<a href="Angular/1">Topic details</a>

<script>
sampleApp.config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider) {
  $locationProvider.html5Mode(true);
  $routeProvider.
  when('/Angular/:topicId', {
    templateUrl: 'Angular.html',
    controller: 'AngularController'
  });
}]);
</script>

⚠️ การแก้ไข: เดิมทีประกาศไว้ว่า baseUrl ชี้ไปยังพาธ IDE ในเครื่องอย่างคงที่ ซึ่งไม่มีผลต่อ html5Mode AngularJS อ่านตำแหน่งฐานจาก <base href> แท็ก ต้นฉบับยังฉีดเข้าไปด้วย $locationProvider โดยไม่เคยโทรเลย html5Mode(true)ดังนั้นแฮชจึงไม่เคยถูกลบออก

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

Output:

การเปิดใช้งานการกำหนดเส้นทาง HTML5

จากผลลัพธ์ที่ได้

  • คุณจะเห็นว่าไม่มีแท็ก # เมื่อเข้าถึงแอปพลิเคชัน

โค้ดด้านบนทั้งหมดใช้ ngRoute ซึ่งเป็นเราเตอร์ที่ทีม AngularJS จัดส่งมาให้ อย่างไรก็ตาม มันไม่ใช่ตัวเลือกเดียว และการเปรียบเทียบด้านล่างจะอธิบายว่าเมื่อใดที่ตัวเลือกอื่นเหมาะสมกว่า

ngRoute กับ ui-router: ควรเลือกใช้เราเตอร์ตัวไหนดี

ngRoute ถูกดูแลโดยทีม AngularJS และตรงกับ... URL โดยตรงไปยังเทมเพลตและคอนโทรลเลอร์เดียว ui-router เป็นโปรเจกต์จากชุมชนที่สร้างขึ้นเพื่อขจัดข้อจำกัดหลักของ ngRoute: คือการจับคู่ตามแอปพลิเคชัน รัฐ แทนที่จะอยู่บน URL โดยลำพัง ซึ่งทำให้หน้าจอเดียวสามารถบรรจุพื้นที่ที่เชื่อมต่อกันอย่างอิสระได้หลายส่วน

แง่มุม ngRoute เราเตอร์ UI
บริการการกำหนดค่า $routeProvider $stateProvider
การแข่งขันบน URL เพียง รัฐที่มีชื่อ, URL ไม่จำเป็น
มุมมองแบบซ้อนกัน ไม่ได้รับการสนับสนุน ที่สนับสนุน
หลายมุมมองต่อหน้าจอ หนึ่งมุมมอง เต้ารับ UI-View ที่มีชื่อจำนวนมาก
การแก้ไขแบบซ้อนกัน ไม่ได้รับการสนับสนุน สถานะของลูกจะสืบทอดการแก้ไขจากสถานะแม่
เหมาะที่สุดสำหรับ ใช้งานแบบแบนและขนาดเล็ก แดชบอร์ดและเลย์เอาต์แบบเลเยอร์

เลือก ngRoute เมื่อแต่ละครั้ง URL แมปไปยังมุมมองเต็มหน้าจอเดียว เนื่องจากไม่ต้องการการพึ่งพาเพิ่มเติม และ API ทั้งหมดพอดีกับหน้าเดียว เลือกใช้ ui-router เมื่อหน้าจอมีบานหน้าต่างที่นำทางอย่างอิสระ หรือเมื่อมุมมองย่อยต้องใช้ข้อมูลที่โหลดโดยมุมมองหลักซ้ำ การย้ายไปใช้ในภายหลังเป็นไปได้ แต่ไม่ใช่เรื่องง่าย เนื่องจากชื่อสถานะจะเข้ามาแทนที่ URL ลวดลายต่างๆ ปรากฏอยู่ทั่วทั้งแม่แบบ

ข้อผิดพลาดทั่วไปในการกำหนดเส้นทาง (Routing) ใน AngularJS และวิธีแก้ไข

ความล้มเหลวในการกำหนดเส้นทางส่วนใหญ่มักทำให้หน้าต่าง ng-view แสดงผลว่างเปล่าแทนที่จะแสดงข้อผิดพลาดในคอนโซล ซึ่งทำให้การวินิจฉัยทำได้ยากกว่าที่ควรจะเป็น อาการแต่ละอย่างด้านล่างจะระบุสาเหตุและวิธีแก้ไข

  • ผู้ให้บริการที่ไม่รู้จัก: $routeProvider: ไฟล์ angular-route.js ไม่เคยถูกโหลด หรือถูกโหลดก่อนไฟล์ angular.min.js กรุณาอ้างอิงไลบรารีหลักก่อน
  • หน้าจอยังคงว่างเปล่าโดยไม่มีข้อผิดพลาดใดๆ: ไม่มีองค์ประกอบใดที่ใช้คำสั่ง ng-view ดังนั้นเทมเพลตจึงไม่มีที่สำหรับแสดงผล
  • ไม่มีข้อมูลโหลดในการเข้าชมครั้งแรก: ไม่มีเส้นทางใดตรงกับเส้นทางว่างเปล่า เพิ่มบล็อก otherwise พร้อมค่า redirectTo
  • $routeParams ว่างเปล่า: รูปแบบนี้ขาดตัวยึดตำแหน่งเครื่องหมายโคลอน ที่ถูกต้องควรเป็น '/Angular/:topicId'
  • เทมเพลตแสดงข้อผิดพลาด 404 หลังจาก html5Mode: กำหนดค่าเซิร์ฟเวอร์ให้เขียนเส้นทางที่ไม่ตรงกันใหม่ไปยังหน้าหลัก และตรวจสอบว่าแท็ก href ของหน้าหลักมีอยู่หรือไม่
  • ตัวควบคุมจะไม่ทำงานซ้ำอีก: มีเพียงพารามิเตอร์เท่านั้นที่เปลี่ยนแปลง ดังนั้น AngularJS จึงนำอินสแตนซ์ของคอนโทรลเลอร์มาใช้ซ้ำแทนที่จะสร้างใหม่ทั้งหมด ควรฟังเหตุการณ์ `$routeUpdate` แทนที่จะรอให้ฟังก์ชันของคอนโทรลเลอร์ทำงานอีกครั้ง

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

`$routeParams` จะส่งคืนทั้งตัวยึดตำแหน่งเส้นทางและค่าสตริงคำค้นหาที่รวมอยู่ในอ็อบเจ็กต์เดียว ส่วน `$location.search()` จะส่งคืนเฉพาะสตริงคำค้นหาเท่านั้น ควรใช้ `$routeParams` ภายในคอนโทรลเลอร์ และใช้ `$location.search()` เมื่อต้องการอ่านหรือเขียนค่าคำค้นหาโดยตรง

ใช่แล้ว หากไม่มีแฮช เบราว์เซอร์จะส่งพาธแบบเต็มไปยังเซิร์ฟเวอร์เมื่อมีการรีเฟรชหน้าเว็บหรือมีการแชร์ลิงก์ เซิร์ฟเวอร์จะต้องเขียนพาธที่ไม่ตรงกันทั้งหมดใหม่ให้กลับไปเป็นหน้า HTML พื้นฐาน มิฉะนั้นลิงก์แบบเจาะลึกจะแสดงข้อผิดพลาด 404

AngularJS สิ้นสุดการสนับสนุนในเดือนธันวาคม 2021 และจะไม่ได้รับการอัปเดตเพิ่มเติมอีกต่อไป ngRoute ยังคงเหมาะสมสำหรับการบำรุงรักษาแอปพลิเคชัน AngularJS ที่มีอยู่ แต่สำหรับโครงการใหม่ ควรใช้เฟรมเวิร์กที่ได้รับการสนับสนุนในปัจจุบันแทน

ใช่. AI ผู้ช่วยจะแมปแต่ละบล็อก when ไปยังรายการในอาร์เรย์ Routes และแปลงคีย์ resolve เป็นตัวแก้ไขเส้นทาง (route resolver) Revต้องตั้งค่าการ์ดตรวจสอบและจัดการไวลด์การ์ดด้วยตนเอง เนื่องจากเราเตอร์ทั้งสองตัวจัดการเส้นทางที่ไม่ตรงกันแตกต่างกัน

เครื่องมือ AI จะตรวจสอบสาเหตุทั่วไปสามประการตามลำดับ ได้แก่ การขาดการพึ่งพา ngRoute, การไม่มีองค์ประกอบ ng-view และรูปแบบเส้นทางที่ไม่ตรงกัน URLการอธิบายอาการและคัดลอกส่วนของโค้ดการตั้งค่าลงไป มักจะช่วยระบุสาเหตุของปัญหาได้

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