ในขั้นตอนนี้เราจะปรับปรุงวิธีที่แอปของเราได้รับข้อมูล
โปรดรีเซ็ตไดเรกทอรีการทำงาน:
git checkout -f step -11
การปรับปรุงครั้งสุดท้ายสำหรับแอปพลิเคชันของเราคือการกำหนดบริการที่กำหนดเองที่แสดงถึงลูกค้าที่อยู่อาศัย ด้วยลูกค้ารายนี้เราสามารถส่งคำขอ XHR ได้ง่ายขึ้นโดยไม่ต้องดูแลเกี่ยวกับบริการ $ HTTP พื้นฐาน (API, HTTP วิธีการและ URL)
ความแตกต่างที่สำคัญที่สุดระหว่างขั้นตอนที่ 9 และขั้นตอนที่ 10 อยู่ด้านล่าง คุณสามารถเห็นความแตกต่างที่สมบูรณ์ใน GitHub
เทมเพลต
บริการที่กำหนดเองถูกกำหนดไว้ในแอพ/js/บริการดังนั้นเราจำเป็นต้องแนะนำไฟล์นี้ในเทมเพลตเลย์เอาต์ นอกจากนี้เรายังต้องโหลดไฟล์ AngularJS-resource.js ซึ่งมีโมดูล Ngresource และบริการ $ Resource ในนั้น เราจะใช้ในภายหลัง:
App/index.html
... <script src = "js/services.js"> </script> <script src = "lib/angular/angular-resource.js"> </script> ...
ให้บริการ
แอพ/js/services.js
Angular.module ('Phonecatservices', ['Ngresource']) โรงงาน ('โทรศัพท์', ฟังก์ชั่น ($ ทรัพยากร) {return $ resource ('โทรศัพท์/: phone.json', {}, {query: {วิธี: 'get', params: {phoneid: 'โทรศัพท์'}, isarray: true}});});เราใช้โมดูล API เพื่อลงทะเบียนบริการที่กำหนดเองด้วยวิธีการโรงงาน เราผ่านฟังก์ชั่นโทรศัพท์ชื่อบริการและฟังก์ชั่นโรงงาน ฟังก์ชั่นจากโรงงานและตัวสร้างคอนโทรลเลอร์มีความคล้ายคลึงกันและพวกเขาทั้งคู่ประกาศบริการการพึ่งพาผ่านพารามิเตอร์ฟังก์ชั่น บริการโทรศัพท์ประกาศว่าขึ้นอยู่กับบริการ $ Resource
บริการ $ Resource ช่วยให้คุณสามารถสร้างไคลเอนต์ RESTFUL ในรหัสเพียงไม่กี่บรรทัด แอปพลิเคชันของเราใช้ไคลเอนต์นี้เพื่อแทนที่บริการ $ http พื้นฐาน
แอพ/js/app.js
... angular.module ('phonecat', ['phonecatfilters', 'phonecatservices']) ...เราจำเป็นต้องเพิ่ม phonecatservices ไปยังอาร์เรย์การพึ่งพา Phonecat
ผู้ควบคุม
ด้วยการปรับแต่งบริการ $ http พื้นฐานและวางไว้ในโทรศัพท์บริการใหม่เราสามารถลดความซับซ้อนของ subcontrollers (phonelistctrl และ phoneedetailctrl ได้อย่างง่ายดาย ทรัพยากร $ ของ AngularJS เหมาะสำหรับการโต้ตอบกับแหล่งข้อมูลแบบพักผ่อนมากกว่า $ http และตอนนี้มันง่ายกว่าที่เราจะเข้าใจว่ารหัสคอนโทรลเลอร์กำลังทำอะไรอยู่
แอพ/js/controllers.js
... ฟังก์ชั่น phonelistctrl ($ scope, โทรศัพท์) {$ scope.phones = phone.query (); $ scope.orderprop = 'age';} // phonelistctrl. $ inject = ['$ scope', 'โทรศัพท์']; ฟังก์ชั่นโทรศัพท์ phonedetailctrl ($ scope, $ touryparams, โทรศัพท์) {$ scope.phone = โทรศัพท์ get $ scope.setImage = function (imageUrl) {$ scope.mainimageUrl = imageUrl; }} // phoneDetailctrl. $ inject = ['$ scope', '$ routeparams', 'โทรศัพท์'];โปรดทราบว่าใน phonelistctrl เราใส่:
$ http.get ('โทรศัพท์/phone.json'). ความสำเร็จ (ฟังก์ชั่น (ข้อมูล) {$ scope.phones = data;});เปลี่ยนเป็น:
$ scope.phones = phone.query ();
เราใช้คำสั่งง่ายๆนี้เพื่อค้นหาโทรศัพท์มือถือทั้งหมด
อีกสิ่งหนึ่งที่ต้องสังเกตคือในรหัสข้างต้นเมื่อโทรหาวิธีการบริการโทรศัพท์คือเราไม่ผ่านฟังก์ชั่นการโทรกลับใด ๆ แม้ว่าสิ่งนี้จะถูกส่งคืนแบบซิงโครนัส แต่ก็ไม่ได้เลย สิ่งที่ส่งคืนแบบซิงโครนัสคือ "อนาคต" - วัตถุซึ่งจะเต็มไปด้วยข้อมูลเมื่อ XHR ส่งคืนตามลำดับ เมื่อได้รับการเชื่อมโยงข้อมูลของ AngularJS เราสามารถใช้อนาคตและผูกกับเทมเพลตของเรา มุมมองของเราจะอัปเดตโดยอัตโนมัติเมื่อข้อมูลมาถึง
บางครั้งการพึ่งพาวัตถุในอนาคตและการเชื่อมโยงข้อมูลไม่เพียงพอที่จะตอบสนองความต้องการของเราดังนั้นในกรณีเหล่านี้เราจำเป็นต้องเพิ่มฟังก์ชั่นการโทรกลับเพื่อจัดการกับการตอบสนองของเซิร์ฟเวอร์ คอนโทรลเลอร์โทรศัพท์ phoneedetailctrl เป็นคำอธิบายโดยการตั้งค่า MainImageUrl ในฟังก์ชั่นการโทรกลับ
ทดสอบ
ปรับเปลี่ยนการทดสอบหน่วยของเราเพื่อตรวจสอบว่าบริการใหม่ของเราเริ่มต้นคำขอ HTTP และดำเนินการตามที่คาดไว้ การทดสอบยังตรวจสอบว่าคอนโทรลเลอร์ของเราทำงานอย่างถูกต้องกับบริการหรือไม่
บริการ $ Resource ช่วยเพิ่มวัตถุที่ได้จากการเพิ่มการอัปเดตและการลบทรัพยากร หากเราตั้งใจจะใช้ตัวจับคู่ที่มีความเท่าเทียมกันการทดสอบของเราจะล้มเหลวเนื่องจากค่าการทดสอบจะไม่เทียบเท่ากับการตอบสนองอย่างแน่นอน เพื่อแก้ปัญหานี้เราจำเป็นต้องใช้ตัวจับคู่ toequaldatajasmine ที่กำหนดเมื่อเร็ว ๆ นี้ เมื่อตัวจับคู่ Toequaldata เปรียบเทียบสองวัตถุมันจะพิจารณาคุณสมบัติของวัตถุเท่านั้นและละเว้นวิธีการทั้งหมด
ทดสอบ/หน่วย/controllersspec.js:
อธิบาย ('phonecat controllers', function () {beforeeach (function () {this.addmatchers ({toequaldata: ฟังก์ชั่น (คาดว่า) {return angular.equals (this.actual, คาดว่า);}});}); ก่อนหน้า $ httpbackend; $ rootscope. $ new (); [{ชื่อ: 'Nexus S'}, {ชื่อ: 'Motorola Droid'}]); xyzphonedata = function () {return {ชื่อ: 'โทรศัพท์ xyz', รูปภาพ: ['image/url1.png', 'image/url2.png']}}; $ httpbackend.expectget ('โทรศัพท์/xyz.json') ตอบสนอง (xyzphonedata ()); คาดหวัง (popeshone) .toequaldata ({});ดำเนินการ ./scripts/test.sh เพื่อเรียกใช้การทดสอบและคุณควรดูผลลัพธ์ต่อไปนี้:
Chrome: Runner Reset ...... การทดสอบทั้งหมด 4 ครั้ง (ผ่าน: 4; Fails: 0; ข้อผิดพลาด: 0) (3.00 ms) Chrome 19.0.1084.36 Mac OS: Run 4 การทดสอบ (ผ่าน: 4; Fails: 0; ข้อผิดพลาด 0) (3.00 ms)
สรุป
สมบูรณ์! คุณได้สร้างเว็บแอปพลิเคชันในเวลาอันสั้น ในบทสุดท้ายเราจะพูดถึงสิ่งที่เราควรทำต่อไป
ข้างต้นคือข้อมูลการแยกส่วน AngularJS และบริการที่กำหนดเอง เราจะยังคงเพิ่มข้อมูลที่เกี่ยวข้องในอนาคต ฉันหวังว่ามันจะช่วยให้ทุกคนเรียนรู้ AngularJs!