RESTful thông qua $resource của AngularJS
Bài đăng này đã không được cập nhật trong 9 năm
I. Mở đầu
1. $resource là gì?
$resrouce
là một service nó không có sẵn trong thư viện của AngularJS. Bạn phải download nó và include vào trong ứng dụng.
<script type="text/javascript" src="angular.js"></script>
<script type="text/javascript" src="angular-resource.js"></script>
$resource
là một factory nó tạo ra một resource object cho phép chúng tương tác với RESTful phía server.- The returned resource object has action methods which provide high-level behaviors without the need to interact with the low level $http service.
- Resource object có đầy đủ các phương thức cho các hành vi khác nhau mà không cần phải tương tác với các service của $http (low level)
2. $http vs $resource
a. $http
$http service
là một dịch vụ cốt lõi của Angular, được sử dụng để giao tiếp với các trình chủ HTTP thông qua các đối tượng XMLHttpRequest của trình duyệt.
$http service
gần giống như phương thức $.ajax() trong jQuery. $http sẽ request và được trả về một promise.
$http
chỉ dùng cho việc gọi Ajax thông thường với các phương thức get, post, delete, put....
- $http.get(url, [config])
- $http.delete(url, [config])
- $http.head(url, [config])
- $http.patch(url, data, [config])
- $http.post(url, data, [config])
- $http.put(url, data, [config])
- $http.jsonp(url, [config])
Chú ý rằng, phương thức $http.post(), $http.put() và $http.patch() có tham số data chứa dữ liệu được gửi đến server. Các phương thức còn lại không thể có tham số data.
Tham số data là một chuỗi JSON được đưa vào trong phần request body. AngularJS sẽ coi tất cả các thuộc tính bắt đầu với ký tự $ là của riêng nó, do đó nó sẽ loại bỏ $ ra khỏi data. Nếu dữ liệu của bạn cần chứa các thuộc tính bắt đầu với $ thì bạn cần chuyển đối tượng data thành chuỗi của riêng bạn bằng cách sử dụng hàm JSON.stringify(data)
b. $resource
$resource
được xây dựng dựa trên $http
$resource
giúp cho việc xây dựng một ứng dụng RESTful backend trở nên dễ dàng hơn, code ngắn gọn hơn
II. Cách thức hoạt động của $resource
1. Sử dụng $resource
- AngularJS cung cấp dịch vụ
$resource
thông qua modulengResource
angular.module('mainApp',['ngResource']);
- Bạn có thể sử dụng
$resource
trong (service, controller ... )
2. Thành phần và hoạt động
$resource
làm việc với RESTful backend theo quy tắc:
URL | Http verb | Body request |
---|---|---|
http://localhost:3000/api/v1/words | GET | Rỗng |
http://localhost:3000/api/v1/words | POST | Json |
http://localhost:3000/api/v1/words/:id | GET | Rỗng |
http://localhost:3000/api/v1/words/:id | PUT | JSON |
http://localhost:3000/api/v1/words/:id | DELETE | Rỗng |
angular.module('mainApp').factory('Word', function($resource) {
return $resource('/api/v1/words/:id');
});
$resource
sẽ trả về một resource class với 5 phương thức mặc định: get(), save(), query(), remove(), delete()
ví dụ
angular.module('myApp.controllers',[]);
angular.module('myApp.controllers').controller('ResourceController',function($scope, Word) {
var word = Word.get({ id: $scope.id }, function() {
// something
}); // get() trả về một word
var words = Word.query(function() {
// something
}); //query() trả về một mảng words
$scope.word = new Word(); Một resource instance
$scope.word.content = 'New word';
Entry.save($scope.entry, function() {
//do something
});
});
Hàm get()
- Hàm get() sẽ request với phương thức GET đến
/api/v1/words/:id
. Tham số id trên url sẽ được thay bởi$scope
. Hàm get() sẽ trả về đối tượng rỗng và nó chỉ nó được tự động cập nhật khi có data từ phía server trả về. - Tham số thứ 2 trong hàm get() là một callback được gọi khi có data từ phía server trả về.
Hàm query()
- Hàm này sẽ request với phương thức GET đến
/api/v1/words
và trả về một mảng rỗng. Và mảng này được update khi có data từ server trả về, cũng giống như kiểu trả về của hàm get(). Và callback của hàm query() sẽ được gọi mỗi khi có data từ phía server trả về.
Hàm save()
- Hàm save() sẽ request một với phương thức POST đến
/api/v1/words
. Tham số đầu là data body, tham số thứ 2 là một callback được gọi khi data được lưu. - Ta có thể gọi lại một resource class, thiết lập các thuộc tính cho nó và lưu trữ đối tượng vào phía server
3. Các action method của Resource Class và Resource Instance
-
HTTP GET "class" actions: Resource.action([parameters], [success], [error])
-
non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
-
non-GET instance actions: instance.$action([parameters], [success], [error])
Class action gọi phương thức sẽ không có tiền tố $, đối với instance action thì ngược lại.
Word= $resource('/api/v1/words/:id, {id:'@id'});
word = Word.get(id: 11)
Word.save(word) tương đương với word.$save()
Word
gọi là resource refactor.
$resource
gọi là resource constructor.
- Success callback được gọi với các tham số (value, responseHeaders), value là resource instance hoặc các collection object.
- Error callback được gọi với một tham số (httpResponse)
- Class action trả về các empty instance, trong khi đó instance action trả về promise của action
Các Resource instance và collection có các thuộc tính:
$promise
: việc thực hiện các request thông qua web service thường trả lại dữ liệu với độ trễ nhất định. Để đảm bảo dữ liệu đã sẵn sàng trước khi gán nó vào model hoặc render lên view, chúng ta có thể sử dụng promise.
$resolved
: mặc định là false, sau khi tương tác với server lần đầu tiên hoàn thành (dù success hay fail) nó được thiết lập giá trị true.
III. Ứng dụng
controllers/words_controller.js
angular.module('wordApp.controllers', []).controller('WordListController', function($scope, $state, popupService, $window, Word) {
$scope.words = Word.query();
$scope.deleteWord = function(word) {
if (popupService.showPopup('Really delete this?')) {
word.$delete(function() {
$window.location.href = ''; //redirect to home
});
}
};
}).controller('WordShowController', function($scope, $stateParams, Word) {
$scope.word = Word.get({ id: $stateParams.id });
}).controller('WordCreateController', function($scope, $state, $stateParams, Word) {
$scope.word = new Word();
$scope.addWord = function() {
$scope.word.$save(function() {
$state.go('words');
});
};
}).controller('WordEditController', function($scope, $state, $stateParams, Word) {
$scope.updateWord = function() {
$scope.word.$update(function() {
$state.go('words');
});
};
$scope.loadWord = function() {
$scope.word = Word.get({ id: $stateParams.id });
};
$scope.loadWord();
});
words/app.js
Chú ý routes sử dụng Angular UI Routes bạn có thể tham khảo cách cài đặt và dùng ở đây https://github.com/angular-ui/ui-router
angular.module('wordApp', ['ui.router', 'ngResource', 'wordApp.controllers', 'wordApp.services']);
angular.module('wordApp').config(function($stateProvider) {
$stateProvider.state('words', {
url: '/api/v1/words',
templateUrl: '/templates/words.html',
controller: 'WordListController'
}).state('showWord', {
url: '/api/v1/words/:id/view',
templateUrl: '/templates/show.html',
controller: 'WordShowController'
}).state('newWord', {
url: '/api/v1/words/new',
templateUrl: '/templates/add.html',
controller: 'WordCreateController'
}).state('editWord', {
url: '/api/words/:id/edit',
templateUrl: '/templates/edit.html',
controller: 'WordEditController'
});
}).run(function($state) {
$state.go('words');
});
Mỗi một state sẽ bao gồm url, template và controller. Như trên thì newWord
là một state đi đến trang new
services.js
angular.module('wordApp.services', []).factory('Word', function($resource) {
return $resource('http://localhost:3000/api/v1/words/:id', { id: '@_id' }, {
update: {
method: 'PUT'
}
});
});
Tham khảo ứng dụng tại đây AngularJS
IV. Nguồn tham khảo
All rights reserved