บทแนะนำทีละขั้นตอนสำหรับแอป AngularJS แรกของคุณ
เผยแพร่แล้ว: 2022-03-11AngularJS คืออะไร?
AngularJS เป็นเฟรมเวิร์ก JavaScript MVC ที่พัฒนาโดย Google ซึ่งช่วยให้คุณสร้างแอปพลิเคชันส่วนหน้าที่มีโครงสร้างดี ทดสอบได้ง่าย และบำรุงรักษาได้
และทำไมฉันจึงควรใช้มัน?
หากคุณยังไม่ได้ลองใช้ AngularJS ถือว่าคุณพลาด เฟรมเวิร์กประกอบด้วยชุดเครื่องมือที่ผสานรวมอย่างแน่นหนา ซึ่งจะช่วยให้คุณสร้างแอปพลิเคชันฝั่งไคลเอ็นต์ที่มีโครงสร้างที่ดีและสมบูรณ์ในรูปแบบโมดูลาร์—ด้วยโค้ดที่น้อยลงและความยืดหยุ่นที่มากขึ้น
AngularJS ขยาย HTML โดยให้คำสั่งที่เพิ่มฟังก์ชันการทำงานให้กับมาร์กอัปของคุณและช่วยให้คุณสร้างเทมเพลตแบบไดนามิกที่มีประสิทธิภาพ คุณยังสามารถสร้างคำสั่งของคุณเอง ประดิษฐ์ส่วนประกอบที่นำกลับมาใช้ใหม่ได้ซึ่งเติมเต็มความต้องการของคุณ และแยกตรรกะการจัดการ DOM ทั้งหมดออกไป
นอกจากนี้ยังใช้การเชื่อมโยงข้อมูลแบบสองทาง โดยเชื่อมต่อ HTML (มุมมอง) กับออบเจกต์ JavaScript (โมเดล) ได้อย่างราบรื่น พูดง่ายๆ ก็คือ หมายความว่าการอัปเดตใดๆ บนโมเดลของคุณจะมีผลทันทีในมุมมองของคุณ โดยไม่ต้องมีการจัดการ DOM หรือการจัดการเหตุการณ์ (เช่น ด้วย jQuery)
สุดท้ายนี้ ฉันชอบ Angular เพราะมีความยืดหยุ่นในการสื่อสารกับเซิร์ฟเวอร์ เช่นเดียวกับเฟรมเวิร์ก JavaScript MVC ส่วนใหญ่ มันให้คุณทำงานกับเทคโนโลยีฝั่งเซิร์ฟเวอร์ใดๆ ก็ได้ตราบเท่าที่สามารถให้บริการแอปของคุณผ่าน RESTful web API แต่ Angular ยังให้บริการนอกเหนือ จาก XHR ที่ทำให้โค้ดของคุณง่ายขึ้นอย่างมาก และช่วยให้คุณสามารถเรียก API ที่เป็นนามธรรมลงในบริการที่นำกลับมาใช้ใหม่ได้ ด้วยเหตุนี้ คุณจึงสามารถย้ายโมเดลและตรรกะทางธุรกิจของคุณไปยังส่วนหน้าและสร้างเว็บแอปแบบไม่เชื่อเรื่องพระเจ้าส่วนหลังได้ ในโพสต์นี้ เราจะทำอย่างนั้นทีละขั้นตอน
ดังนั้นฉันจะเริ่มต้นที่ไหน
อันดับแรก มาตัดสินใจเลือกลักษณะของแอพที่เราต้องการสร้างกันก่อน ในคู่มือนี้ เราไม่ต้องการใช้เวลามากเกินไปกับแบ็คเอนด์ ดังนั้นเราจะเขียนบางอย่างโดยอิงจากข้อมูลที่เข้าถึงได้ง่ายบนอินเทอร์เน็ต เช่น แอปฟีดกีฬา!
เนื่องจากฉันเป็นแฟนตัวยงของการแข่งรถและ Formula 1 ฉันจะใช้บริการ autosport API เพื่อทำหน้าที่เป็นแบ็กเอนด์ของเรา โชคดีที่ทีมงานที่ Ergast ใจดีพอที่จะให้ API มอเตอร์สปอร์ตฟรีซึ่งเหมาะสำหรับเรา
สำหรับการแอบดูสิ่งที่เรากำลังจะสร้าง ให้ดูที่การสาธิตสด เพื่อทำให้การสาธิตดูสวยงามและอวดการสร้างเทมเพลตเชิงมุม ฉันจึงใช้ธีม Bootstrap จาก WrapBootstrap แต่เมื่อเห็นว่าบทความนี้ไม่เกี่ยวกับ CSS ฉันจะแยกมันออกจากตัวอย่างและปล่อยมันออกไป
เริ่มต้นการสอน
มาเริ่มต้นแอปตัวอย่างของเราด้วยต้นแบบกันเถอะ ฉันแนะนำโปรเจ็กต์ angular-seed เนื่องจากมันไม่เพียงแต่ให้โครงร่างที่ยอดเยี่ยมสำหรับการบูตสแตรป แต่ยังสร้างพื้นฐานสำหรับการทดสอบหน่วยด้วย Karma และ Jasmine (เราจะไม่ทำการทดสอบใดๆ ในการสาธิตนี้ ดังนั้นเราจะทำ ทิ้งสิ่งนั้นไว้ก่อน ดูส่วนที่ 2 ของบทช่วยสอนนี้สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการตั้งค่าโครงการของคุณสำหรับหน่วยและการทดสอบแบบ end-to-end)
แก้ไข (พฤษภาคม 2014): เนื่องจากฉันเขียนบทช่วยสอนนี้ โครงการ angular-seed ได้ผ่านการเปลี่ยนแปลงครั้งใหญ่ (รวมถึงส่วนเพิ่มเติมของ Bower ในฐานะผู้จัดการแพ็คเกจ) หากคุณมีข้อสงสัยเกี่ยวกับวิธีการปรับใช้โครงการ ให้ดูที่ส่วนแรกของคู่มืออ้างอิงอย่างรวดเร็ว ในส่วนที่ 2 ของบทช่วยสอนนี้ Bower รวมถึงเครื่องมืออื่นๆ จะกล่าวถึงรายละเอียดเพิ่มเติม
ตกลง ตอนนี้เราได้โคลนที่เก็บและติดตั้งการพึ่งพาแล้ว โครงกระดูกของแอปของเราจะมีลักษณะดังนี้:
ตอนนี้เราสามารถเริ่มเขียนโค้ดได้แล้ว ขณะที่เรากำลังพยายามสร้างฟีดกีฬาสำหรับการแข่งขันชิงแชมป์ เรามาเริ่มด้วยมุมมองที่เกี่ยวข้องกันมากที่สุด: ตารางการแข่งขันชิงแชมป์
เนื่องจากเรามีรายชื่อไดรเวอร์ที่กำหนดไว้ภายในขอบเขตของเราแล้ว (เดี๋ยวรอเดี๋ยวก็ถึง) และไม่สนใจ CSS ใดๆ (เพื่อให้อ่านง่าย) HTML ของเราอาจมีลักษณะดังนี้:
<body ng-app="F1FeederApp" ng-controller="driversController"> <table> <thead> <tr><th colspan="4">Drivers Championship Standings</th></tr> </thead> <tbody> <tr ng-repeat="driver in driversList"> <td>{{$index + 1}}</td> <td> <img src="img/flags/{{driver.Driver.nationality}}.png" /> {{driver.Driver.givenName}} {{driver.Driver.familyName}} </td> <td>{{driver.Constructors[0].name}}</td> <td>{{driver.points}}</td> </tr> </tbody> </table> </body>
สิ่งแรกที่คุณจะสังเกตเห็นในเทมเพลตนี้คือการใช้นิพจน์ (“{{“ และ “}}”) เพื่อส่งกลับค่าตัวแปร ในการพัฒนา AngularJS นิพจน์ช่วยให้คุณดำเนินการคำนวณบางอย่างเพื่อคืนค่าที่ต้องการ นิพจน์ที่ถูกต้องบางนิพจน์จะเป็น:
-
{{ 1 + 1 }}
-
{{ 946757880 | date }}
-
{{ user.name }}
อย่างมีประสิทธิภาพ นิพจน์เป็นตัวอย่างที่เหมือน JavaScript แต่ถึงแม้จะทรงพลังมาก คุณไม่ควรใช้นิพจน์เพื่อนำตรรกะระดับสูงกว่าไปใช้ เพื่อที่เราใช้คำสั่ง
การทำความเข้าใจคำสั่งพื้นฐาน
สิ่งที่สองที่คุณจะสังเกตเห็นคือการมีอยู่ของ ng-attributes
ซึ่งคุณจะไม่เห็นในมาร์กอัปทั่วไป นั่นคือคำสั่ง
ในระดับสูง คำสั่งคือเครื่องหมาย (เช่น แอตทริบิวต์ แท็ก และชื่อคลาส) ที่บอกให้ AngularJS แนบพฤติกรรมที่กำหนดกับองค์ประกอบ DOM (หรือแปลง แทนที่ เป็นต้น) เรามาดูกันดีกว่าว่า:
ng-app
directive มีหน้าที่รับผิดชอบในการบูตแอพของคุณเพื่อกำหนดขอบเขต ใน AngularJS คุณสามารถมีแอปได้หลายแอปในหน้าเดียวกัน ดังนั้นคำสั่งนี้จะกำหนดว่าแต่ละแอปเริ่มต้นและสิ้นสุดที่ใดng-controller
directive กำหนดว่าคอนโทรลเลอร์ใดจะทำหน้าที่ดูแลมุมมองของคุณ ในกรณีนี้ เราหมายถึงdriversController
ซึ่งจะให้รายชื่อไดรเวอร์ของเรา (driversList
)ng-repeat
directive เป็นหนึ่งในคำสั่งที่ใช้บ่อยที่สุดและใช้เพื่อกำหนดขอบเขตเทมเพลตของคุณเมื่อวนลูปผ่านคอลเล็กชัน ในตัวอย่างข้างต้น จะจำลองบรรทัดในตารางสำหรับไดรเวอร์แต่ละตัวในdriversList
การเพิ่มตัวควบคุม
แน่นอนว่ามุมมองของเราไม่มีประโยชน์หากไม่มีตัวควบคุม มาเพิ่ม driversController
ให้กับ controllers.js ของเรา:
angular.module('F1FeederApp.controllers', []). controller('driversController', function($scope) { $scope.driversList = [ { Driver: { givenName: 'Sebastian', familyName: 'Vettel' }, points: 322, nationality: "German", Constructors: [ {name: "Red Bull"} ] }, { Driver: { givenName: 'Fernando', familyName: 'Alonso' }, points: 207, nationality: "Spanish", Constructors: [ {name: "Ferrari"} ] } ]; });
คุณอาจสังเกตเห็นตัวแปร $scope
ที่เรากำลังส่งผ่านเป็นพารามิเตอร์ไปยังตัวควบคุม ตัวแปร $scope
ควรจะเชื่อมโยงคอนโทรลเลอร์และมุมมองของคุณ โดยเฉพาะอย่างยิ่ง จะเก็บข้อมูลทั้งหมดที่จะใช้ภายในเทมเพลตของคุณ ทุกสิ่งที่คุณเพิ่มเข้าไป (เช่นรายการ driversList
ในตัวอย่างด้านบน) จะสามารถเข้าถึงได้โดยตรงในมุมมองของคุณ ในตอนนี้ เรามาทำงานกับ data array จำลอง (คงที่) กันก่อน ซึ่งเราจะแทนที่ด้วยบริการ API ของเราในภายหลัง
ตอนนี้ เพิ่มสิ่งนี้ใน app.js:
angular.module('F1FeederApp', [ 'F1FeederApp.controllers' ]);
ด้วยโค้ดบรรทัดนี้ เราเริ่มต้นแอปของเราและลงทะเบียนโมดูลที่ต้องการ เราจะกลับมาที่ไฟล์นั้น ( app.js
) ในภายหลัง
ตอนนี้เรามารวมทุกอย่างเข้าด้วยกันใน index.html
:
<!DOCTYPE html> <html> <head> <title>F-1 Feeder</title> </head> <body ng-app="F1FeederApp" ng-controller="driversController"> <table> <thead> <tr><th colspan="4">Drivers Championship Standings</th></tr> </thead> <tbody> <tr ng-repeat="driver in driversList"> <td>{{$index + 1}}</td> <td> <img src="img/flags/{{driver.Driver.nationality}}.png" /> {{driver.Driver.givenName}} {{driver.Driver.familyName}} </td> <td>{{driver.Constructors[0].name}}</td> <td>{{driver.points}}</td> </tr> </tbody> </table> <script src="bower_components/angular/angular.js"></script> <script src="bower_components/angular-route/angular-route.js"></script> <script src="js/app.js"></script> <script src="js/services.js"></script> <script src="js/controllers.js"></script> </body> </html>
ข้อผิดพลาดเล็กๆ น้อยๆ ของ Modulo ตอนนี้คุณสามารถบูตแอปและตรวจสอบรายการไดรเวอร์ (คงที่) ได้แล้ว
หมายเหตุ: หากคุณต้องการความช่วยเหลือในการดีบักแอปและการแสดงภาพโมเดลและขอบเขตภายในเบราว์เซอร์ เราขอแนะนำให้คุณดูปลั๊กอิน Batarang ที่ยอดเยี่ยมสำหรับ Chrome
กำลังโหลดข้อมูลจากเซิร์ฟเวอร์
เนื่องจากเรารู้วิธีแสดงข้อมูลของผู้ควบคุมในมุมมองของเราอยู่แล้ว จึงถึงเวลาดึงข้อมูลสดจากเซิร์ฟเวอร์ RESTful
เพื่ออำนวยความสะดวกในการสื่อสารกับเซิร์ฟเวอร์ HTTP AngularJS ให้บริการ $resource
$http
และ $ อดีตเป็นเพียงเลเยอร์ที่ด้านบนของ XMLHttpRequest หรือ JSONP ในขณะที่หลังให้ระดับนามธรรมที่สูงขึ้น เราจะใช้ $http
หากต้องการสรุปการเรียก API เซิร์ฟเวอร์ของเราจากคอนโทรลเลอร์ ให้สร้างบริการที่กำหนดเองซึ่งจะดึงข้อมูลของเราและทำหน้าที่เป็นตัวห่อหุ้มรอบ $http
โดยเพิ่มสิ่งนี้ใน services.js
ของเรา:
angular.module('F1FeederApp.services', []). factory('ergastAPIservice', function($http) { var ergastAPI = {}; ergastAPI.getDrivers = function() { return $http({ method: 'JSONP', url: 'http://ergast.com/api/f1/2013/driverStandings.json?callback=JSON_CALLBACK' }); } return ergastAPI; });
ด้วยสองบรรทัดแรก เราสร้างโมดูลใหม่ ( F1FeederApp.services
) และลงทะเบียนบริการภายในโมดูลนั้น ( ergastAPIservice
) ขอให้สังเกตว่าเราส่ง $http
เป็นพารามิเตอร์ไปยังบริการนั้น สิ่งนี้จะบอกเอ็นจิ้นการพึ่งพาของ Angular ว่าบริการใหม่ของเราต้องการ (หรือ ขึ้นอยู่กับ ) บริการ $http
ในทำนองเดียวกัน เราต้องบอกให้ Angular รวมโมดูลใหม่ของเราไว้ในแอพของเรา มาลงทะเบียนกับ app.js
แทนที่รหัสที่มีอยู่ของเราด้วย:
angular.module('F1FeederApp', [ 'F1FeederApp.controllers', 'F1FeederApp.services' ]);
ตอนนี้ สิ่งที่เราต้องทำคือปรับแต่ง controller.js
เล็กน้อย รวม ergastAPIservice
เป็นการพึ่งพา และเราพร้อมที่จะไป:
angular.module('F1FeederApp.controllers', []). controller('driversController', function($scope, ergastAPIservice) { $scope.nameFilter = null; $scope.driversList = []; ergastAPIservice.getDrivers().success(function (response) { //Dig into the responde to get the relevant data $scope.driversList = response.MRData.StandingsTable.StandingsLists[0].DriverStandings; }); });
โหลดแอปอีกครั้งแล้วดูผลลัพธ์ ขอให้สังเกตว่าเราไม่ได้ทำการเปลี่ยนแปลงใดๆ กับเทมเพลตของเรา แต่เราได้เพิ่มตัวแปร nameFilter
ให้กับขอบเขตของเรา ลองนำตัวแปรนั้นไปใช้

ตัวกรอง
ยอดเยี่ยม! เรามีตัวควบคุมการทำงาน แต่จะแสดงรายการไดรเวอร์เท่านั้น มาเพิ่มฟังก์ชันการทำงานบางอย่างโดยใช้การป้อนข้อความค้นหาแบบธรรมดาซึ่งจะกรองรายการของเรา ให้เพิ่มบรรทัดต่อไปนี้ใน index.html
ของเรา ใต้แท็ก <body>
:
<input type="text" ng-model="nameFilter" placeholder="Search..."/>
ขณะนี้เรากำลังใช้คำสั่ง ng-model
คำสั่งนี้จะผูกฟิลด์ข้อความของเรากับตัวแปร $scope.nameFilter
และทำให้แน่ใจว่าค่าของตัวแปรนั้นจะอัพเดทอยู่เสมอด้วยค่าอินพุต ตอนนี้ มาเยี่ยมชม index.html อีกครั้ง และทำการปรับเปลี่ยนเล็กน้อยในบรรทัดที่มีคำสั่ง ng-repeat
:
<tr ng-repeat="driver in driversList | filter: nameFilter">
บรรทัดนี้บอก ng-repeat
ก่อนส่งออกข้อมูล อาร์เรย์ driversList
จะต้องถูกกรองตามค่าที่เก็บไว้ใน nameFilter
ณ จุดนี้ การผูกข้อมูลแบบสองทางเริ่มต้นขึ้น: ทุกครั้งที่มีการป้อนค่าในช่องค้นหา Angular จะทำให้แน่ใจว่า $scope.nameFilter
ที่เราเชื่อมโยงนั้นได้รับการอัปเดตด้วยค่าใหม่ทันที เนื่องจากการเชื่อมโยงทำงานทั้งสองวิธี ทันทีที่ค่า nameFilter
ได้รับการอัปเดต คำสั่งที่สองที่เชื่อมโยงกับค่านั้น (เช่น ng-repeat
) ก็จะได้รับค่าใหม่และมุมมองจะได้รับการอัปเดตทันที
โหลดแอปซ้ำและตรวจดูแถบค้นหา
สังเกตว่าตัวกรองนี้จะมองหาคำหลักเกี่ยวกับคุณลักษณะทั้งหมดของแบบจำลอง รวมทั้งที่ไม่ได้ใช้ด้วย สมมติว่าเราต้องการกรองตาม Driver.givenName
และ Driver.familyName
ขั้นแรก เราเพิ่มใน driversController
ด้านล่าง $scope.driversList = [];
ไลน์:
$scope.searchFilter = function (driver) { var keyword = new RegExp($scope.nameFilter, 'i'); return !$scope.nameFilter || keyword.test(driver.Driver.givenName) || keyword.test(driver.Driver.familyName); };
ตอนนี้ กลับไปที่ index.html
เราอัปเดตบรรทัดที่มีคำสั่ง ng-repeat
:
<tr ng-repeat="driver in driversList | filter: searchFilter">
โหลดแอปอีกครั้งและตอนนี้เรามีการค้นหาตามชื่อแล้ว
เส้นทาง
เป้าหมายต่อไปของเราคือการสร้างหน้ารายละเอียดผู้ขับขี่ ซึ่งจะทำให้เราคลิกที่ไดรเวอร์แต่ละคนและดูรายละเอียดอาชีพของเขา/เธอ
อันดับแรก ให้รวมบริการ $routeProvider
(ใน app.js
) ซึ่งจะช่วยให้เราจัดการกับ เส้นทางแอปพลิเคชัน ที่หลากหลายเหล่านี้ จากนั้น เราจะเพิ่มเส้นทางดังกล่าวสองเส้นทาง: เส้นทางแรกสำหรับตารางการแข่งขันชิงแชมป์ และอีกเส้นทางสำหรับรายละเอียดผู้ขับขี่ นี่คือ app.js
ใหม่ของเรา:
angular.module('F1FeederApp', [ 'F1FeederApp.services', 'F1FeederApp.controllers', 'ngRoute' ]). config(['$routeProvider', function($routeProvider) { $routeProvider. when("/drivers", {templateUrl: "partials/drivers.html", controller: "driversController"}). when("/drivers/:id", {templateUrl: "partials/driver.html", controller: "driverController"}). otherwise({redirectTo: '/drivers'}); }]);
ด้วยการเปลี่ยนแปลงดังกล่าว การนำทางไปที่ http://domain/#/drivers
จะโหลด driversController
และค้นหามุมมองบางส่วนที่จะแสดงผลเป็น partials/drivers.html
แต่เดี๋ยวก่อน! เรายังไม่มีความคิดเห็นบางส่วนใช่ไหม เราจะต้องสร้างสิ่งเหล่านั้นด้วย
มุมมองบางส่วน
AngularJS จะอนุญาตให้คุณผูกเส้นทางของคุณกับตัวควบคุมและมุมมองเฉพาะ
แต่ก่อนอื่น เราต้องบอก Angular ว่าจะแสดงมุมมองบางส่วนเหล่านี้ที่ไหน สำหรับสิ่งนั้น เราจะใช้คำสั่ง ng-view
โดยแก้ไข index.html
ของเราเพื่อมิเรอร์สิ่งต่อไปนี้:
<!DOCTYPE html> <html> <head> <title>F-1 Feeder</title> </head> <body ng-app="F1FeederApp"> <ng-view></ng-view> <script src="bower_components/angular/angular.js"></script> <script src="bower_components/angular-route/angular-route.js"></script> <script src="js/app.js"></script> <script src="js/services.js"></script> <script src="js/controllers.js"></script> </body> </html>
ตอนนี้ เมื่อใดก็ตามที่เรานำทางผ่านเส้นทางแอปของเรา Angular จะโหลดมุมมองที่เกี่ยวข้องและแสดงผลแทนแท็ก <ng-view>
สิ่งที่เราต้องทำคือสร้างไฟล์ชื่อ partials/drivers.html
และใส่ HTML ตารางแชมป์เปี้ยนของเราไว้ที่นั่น นอกจากนี้ เราจะใช้โอกาสนี้ในการเชื่อมโยงชื่อคนขับกับเส้นทางรายละเอียดคนขับของเรา:
<input type="text" ng-model="nameFilter" placeholder="Search..."/> <table> <thead> <tr><th colspan="4">Drivers Championship Standings</th></tr> </thead> <tbody> <tr ng-repeat="driver in driversList | filter: searchFilter"> <td>{{$index + 1}}</td> <td> <img src="img/flags/{{driver.Driver.nationality}}.png" /> <a href="#/drivers/{{driver.Driver.driverId}}"> {{driver.Driver.givenName}} {{driver.Driver.familyName}} </a> </td> <td>{{driver.Constructors[0].name}}</td> <td>{{driver.points}}</td> </tr> </tbody> </table>
สุดท้าย มาตัดสินใจว่าเราต้องการแสดงอะไรในหน้ารายละเอียด สรุปข้อเท็จจริงที่เกี่ยวข้องทั้งหมดเกี่ยวกับผู้ขับขี่ (เช่น เกิด สัญชาติ) พร้อมตารางสรุปผลล่าสุดของเขา/เธอเป็นอย่างไร ในการทำเช่นนั้น เราเพิ่มใน services.js
:
angular.module('F1FeederApp.services', []) .factory('ergastAPIservice', function($http) { var ergastAPI = {}; ergastAPI.getDrivers = function() { return $http({ method: 'JSONP', url: 'http://ergast.com/api/f1/2013/driverStandings.json?callback=JSON_CALLBACK' }); } ergastAPI.getDriverDetails = function(id) { return $http({ method: 'JSONP', url: 'http://ergast.com/api/f1/2013/drivers/'+ id +'/driverStandings.json?callback=JSON_CALLBACK' }); } ergastAPI.getDriverRaces = function(id) { return $http({ method: 'JSONP', url: 'http://ergast.com/api/f1/2013/drivers/'+ id +'/results.json?callback=JSON_CALLBACK' }); } return ergastAPI; });
ครั้งนี้ เรามอบ ID ของผู้ขับขี่ให้กับบริการ เพื่อให้เราดึงข้อมูลที่เกี่ยวข้องกับไดรเวอร์เฉพาะเท่านั้น ตอนนี้เราแก้ไข controllers.js
:
angular.module('F1FeederApp.controllers', []). /* Drivers controller */ controller('driversController', function($scope, ergastAPIservice) { $scope.nameFilter = null; $scope.driversList = []; $scope.searchFilter = function (driver) { var re = new RegExp($scope.nameFilter, 'i'); return !$scope.nameFilter || re.test(driver.Driver.givenName) || re.test(driver.Driver.familyName); }; ergastAPIservice.getDrivers().success(function (response) { //Digging into the response to get the relevant data $scope.driversList = response.MRData.StandingsTable.StandingsLists[0].DriverStandings; }); }). /* Driver controller */ controller('driverController', function($scope, $routeParams, ergastAPIservice) { $scope.id = $routeParams.id; $scope.races = []; $scope.driver = null; ergastAPIservice.getDriverDetails($scope.id).success(function (response) { $scope.driver = response.MRData.StandingsTable.StandingsLists[0].DriverStandings[0]; }); ergastAPIservice.getDriverRaces($scope.id).success(function (response) { $scope.races = response.MRData.RaceTable.Races; }); });
สิ่งสำคัญที่ควรสังเกตคือเราเพิ่งเพิ่มบริการ $routeParams
ลงในตัวควบคุมไดรเวอร์ บริการนี้จะช่วยให้เราเข้าถึงพารามิเตอร์ URL ของเรา (สำหรับ :id
ในกรณีนี้) โดยใช้ $routeParams.id
ตอนนี้เรามีข้อมูลอยู่ในขอบเขตแล้ว เราต้องการเพียงมุมมองบางส่วนที่เหลืออยู่เท่านั้น มาสร้างไฟล์ชื่อ partials/driver.html
และเพิ่ม:
<section> <a href="./#/drivers"><- Back to drivers list</a> <nav class="main-nav"> <div class="driver-picture"> <div class="avatar"> <img ng-show="driver" src="img/drivers/{{driver.Driver.driverId}}.png" /> <img ng-show="driver" src="img/flags/{{driver.Driver.nationality}}.png" /><br/> {{driver.Driver.givenName}} {{driver.Driver.familyName}} </div> </div> <div class="driver-status"> Country: {{driver.Driver.nationality}} <br/> Team: {{driver.Constructors[0].name}}<br/> Birth: {{driver.Driver.dateOfBirth}}<br/> <a href="{{driver.Driver.url}}" target="_blank">Biography</a> </div> </nav> <div class="main-content"> <table class="result-table"> <thead> <tr><th colspan="5">Formula 1 2013 Results</th></tr> </thead> <tbody> <tr> <td>Round</td> <td>Grand Prix</td> <td>Team</td> <td>Grid</td> <td>Race</td> </tr> <tr ng-repeat="race in races"> <td>{{race.round}}</td> <td><img src="img/flags/{{race.Circuit.Location.country}}.png" />{{race.raceName}}</td> <td>{{race.Results[0].Constructor.name}}</td> <td>{{race.Results[0].grid}}</td> <td>{{race.Results[0].position}}</td> </tr> </tbody> </table> </div> </section>
ขอให้สังเกตว่าตอนนี้เรากำลังนำคำสั่ง ng-show
ไปใช้ให้เกิดประโยชน์ คำสั่งนี้จะแสดงองค์ประกอบ HTML ก็ต่อเมื่อนิพจน์ที่ระบุเป็น true
(เช่น ไม่ใช่ false
หรือ null
) ในกรณีนี้ อวาตาร์จะปรากฏขึ้นก็ต่อเมื่อคอนโทรลเลอร์โหลดอ็อบเจ็กต์ไดรเวอร์ลงในขอบเขตแล้ว
สัมผัสสุดท้าย
เพิ่ม CSS จำนวนมากและแสดงหน้าเว็บของคุณ คุณควรลงเอยด้วยสิ่งนี้:
ตอนนี้คุณพร้อมที่จะเปิดแอปของคุณและตรวจสอบให้แน่ใจว่าทั้งสองเส้นทางทำงานตามที่ต้องการ คุณยังสามารถเพิ่มเมนูสแตติกใน index.html
เพื่อปรับปรุงความสามารถในการนำทางของผู้ใช้ ความเป็นไปได้ไม่มีที่สิ้นสุด
แก้ไข (พฤษภาคม 2014): ฉันได้รับคำขอจำนวนมากสำหรับโค้ดเวอร์ชันที่ดาวน์โหลดได้ซึ่งเราสร้างในบทช่วยสอนนี้ ดังนั้นฉันจึงตัดสินใจเผยแพร่ที่นี่ (ตัด CSS ใดๆ ออกไป) อย่างไรก็ตาม ฉัน ไม่ แนะนำให้ดาวน์โหลดจริง ๆ เนื่องจากคู่มือนี้มีขั้นตอนเดียวที่คุณต้องสร้างแอปพลิเคชันเดียวกันด้วยมือของคุณเอง ซึ่งจะเป็นแบบฝึกหัดการเรียนรู้ที่มีประโยชน์และมีประสิทธิภาพมากกว่ามาก
บทสรุป
ณ จุดนี้ในบทช่วยสอน เราได้ครอบคลุมทุกสิ่งที่คุณต้องการในการเขียนแอปอย่างง่าย (เช่น ตัวป้อน Formula 1) แต่ละหน้าที่เหลือในการสาธิตสด (เช่น ตารางการแข่งขันชิงแชมป์คอนสตรัคเตอร์ รายละเอียดทีม ปฏิทิน) แบ่งปันโครงสร้างพื้นฐานและแนวคิดเดียวกันกับที่เราได้ตรวจสอบที่นี่
สุดท้าย พึงระลึกไว้เสมอว่า Angular เป็นเฟรมเวิร์กที่ทรงพลังมาก และเราแทบจะไม่ได้ขีดข่วนพื้นผิวในแง่ของทุกสิ่งที่มีให้ ในส่วนที่ 2 ของบทช่วยสอนนี้ เราจะยกตัวอย่างว่าเหตุใด Angular จึงโดดเด่นท่ามกลางเฟรมเวิร์ก MVC แบบเพียร์ฟรอนต์เอนด์: ความสามารถในการทดสอบ เราจะทบทวนกระบวนการเขียนและเรียกใช้การทดสอบหน่วยด้วย Karma บรรลุการผสานอย่างต่อเนื่องกับ Yeomen, Grunt และ Bower และจุดแข็งอื่นๆ ของเฟรมเวิร์กส่วนหน้าที่ยอดเยี่ยมนี้