Pada langkah ini, kami akan meningkatkan cara aplikasi kami mendapatkan data.
Harap atur ulang direktori kerja:
git checkout -f langkah -11
Peningkatan terakhir dari aplikasi kami adalah menentukan layanan khusus yang mewakili klien yang tenang. Dengan klien ini, kami dapat mengirim permintaan XHR dengan cara yang lebih mudah tanpa peduli dengan layanan $ HTTP yang mendasari (API, metode HTTP, dan URL).
Perbedaan terpenting antara Langkah 9 dan Langkah 10 tercantum di bawah ini. Anda dapat melihat perbedaan lengkap dalam GitHub.
templat
Layanan khusus didefinisikan dalam APP/JS/Layanan, jadi kami perlu memperkenalkan file ini di templat tata letak. Selain itu, kita juga perlu memuat file AngularJS-RESOURCE.js, yang berisi modul NgreSource dan layanan $ sumber daya di dalamnya. Kami akan menggunakannya nanti:
app/index.html
... <skrip src = "js/services.js"> </script> <script src = "lib/angular/angular-resource.js"> </script> ...
Melayani
App/JS/Services.js
Angular.Module ('PhoneCatServices', ['NgreSource']). factory ('phone', function ($ resource) {return $ resource ('phones/: phoneid.json', {}, {query: {Method: 'get', params: {phoneid: 'phones'}, isArray: true}});});Kami menggunakan API modul untuk mendaftarkan layanan khusus melalui metode pabrik. Kami lulus di telepon layanan dan fungsi pabrik. Fungsi pabrik dan konstruktor pengontrol serupa, dan keduanya menyatakan layanan ketergantungan melalui parameter fungsi. Layanan telepon menyatakan bahwa itu tergantung pada layanan sumber daya $.
Layanan $ sumber daya memungkinkan Anda membuat klien yang tenang hanya dalam beberapa baris kode. Aplikasi kami menggunakan klien ini untuk mengganti layanan $ http yang mendasari.
app/js/app.js
... Angular.Module ('PhoneCat', ['PhoneCatfilters', 'PhoneCatServices']) ...Kita perlu menambahkan phonecatservices ke array ketergantungan phonecat.
Pengontrol
Dengan refactoring layanan $ http yang mendasari dan meletakkannya di telepon layanan baru, kami dapat sangat menyederhanakan subkontroler (PhoneListCtrl dan phonedetailctrl). Sumber Daya $ AngularJS lebih cocok untuk berinteraksi dengan sumber data yang tenang daripada $ HTTP. Dan sekarang lebih mudah bagi kita untuk memahami apa yang dilakukan kode pengontrol.
APP/JS/CONTROLER.JS
... fungsi phoneListCtrl ($ scope, phone) {$ scope.phones = phone.query (); $scope.orderProp = 'age';}//PhoneListCtrl.$inject = ['$scope', 'Phone'];function PhoneDetailCtrl($scope, $routeParams, Phone) { $scope.phone = Phone.get({phoneId: $routeParams.phoneId}, function(phone) { $scope.mainImageUrl = phone.images[0]; }); $ scope.setImage = function (ImageUrl) {$ scope.mainimageUrl = ImageUrl; }} // phonedetailctrl. $ Inject = ['$ scope', '$ routeParams', 'phone'];Perhatikan bahwa di phoneListCtrl kami meletakkan:
$ http.get ('phones/phones.json'). sukses (fungsi (data) {$ scope.phones = data;});Ubah ke:
$ scope.phones = phone.query ();
Kami menggunakan pernyataan sederhana ini untuk menanyakan semua ponsel.
Hal lain yang perlu dicatat adalah bahwa dalam kode di atas, ketika memanggil metode layanan telepon adalah bahwa kami tidak melewati fungsi panggilan balik apa pun. Meskipun ini tampaknya dikembalikan secara serempak, itu tidak sama sekali. Apa yang dikembalikan secara sinkron adalah "masa depan" - objek, yang akan diisi dengan data ketika XHR kembali sesuai. Mengingat ikatan data AngularJS, kita dapat menggunakan masa depan dan mengikatnya ke templat kita. Tampilan kami kemudian secara otomatis akan memperbarui saat data tiba.
Kadang -kadang, hanya mengandalkan objek di masa depan dan pengikatan data tidak cukup untuk memenuhi kebutuhan kita, jadi dalam kasus ini, kita perlu menambahkan fungsi panggilan balik untuk menangani respons server. Pengontrol phonedetailctrl adalah penjelasan dengan mengatur MainiMageUrl dalam fungsi panggilan balik.
tes
Ubah tes unit kami untuk memverifikasi bahwa layanan baru kami memulai permintaan HTTP dan memprosesnya seperti yang diharapkan. Tes ini juga memeriksa apakah pengontrol kami bekerja dengan benar dengan layanan.
Layanan $ sumber daya meningkatkan objek yang diperoleh dengan menambahkan pembaruan dan menghapus sumber daya. Jika kami bermaksud menggunakan pencocokan Toequal, tes kami akan gagal karena nilai tes tidak akan setara dengan respons. Untuk mengatasi masalah ini, kita perlu menggunakan pencocokan Toqualdatajasmine yang baru -baru ini didefinisikan. Ketika pencocokan ToEqequaldata membandingkan dua objek, itu hanya mempertimbangkan sifat objek dan mengabaikan semua metode.
Tes/Unit/Controllersspec.js:
describe('PhoneCat controllers', function() { beforeEach(function(){ this.addMatchers({ toEqualData: function(expected) { return angular.equals(this.actual, expected); } }); }); beforeEach(module('phonecatServices')); describe('PhoneListCtrl', function(){ var scope, ctrl, $ httpbackend; sebelum reach (inject (function (_ $ httpbackend_, $ rootscope, $ controller) {$ httpbackend = _ $ httpbackend_; $ httpbackend) ('phones/phones.json'). respond ([{name: 'nexus (' phones/phones.json '). $ rootscope. $ new (); [Name: 'Nexus S'}, {name: 'Motorola Droid'}])); xyzphonedata = function () {return {name: 'phone xyz', gambar: ['image/url1.png', 'image/url2.png']}}; $ httpbackend.Expectget ('Telepon/XYZ.JSON'). harganya (scope.phone) .toequaldata ({});Mengeksekusi ./scripts/test.sh untuk menjalankan tes, dan Anda akan melihat output berikut:
Chrome: Runner Reset ...... Total 4 Tes (Lulus: 4; Gagal: 0; Kesalahan: 0) (3.00 ms) Chrome 19.0.1084.36 Mac OS: Jalankan 4 Tes (Lulus: 4; Gagal: 0; Kesalahan 0) (3.00 ms)
Meringkaskan
Selesai! Anda telah membuat aplikasi web dalam waktu yang cukup singkat. Di bab terakhir, kita akan menyebutkan apa yang harus kita lakukan selanjutnya.
Di atas adalah informasi yang menyortir rest dan layanan khusus. Kami akan terus menambahkan informasi yang relevan di masa mendatang. Saya harap ini dapat membantu semua orang belajar AngularJS!