Restangular是一个专门用来从外部读取数据的AngularJS服务
Restangular依赖Lo-Dash或Underscore,12bet,因此为了确保Restangular可以正常运行,12博体育,需要引入这两个库中的一个
12bet,可以为拉取数据的对象设置基础路由,12bet,会让所有的HTTP请求将该路径作为根路径来拉取数据:
var User = Restangular.all('users');
var allUsers = User.getList(); // GET /users
也可以通过单个对象来发送嵌套的请求:
var oneUser = Restangular.one('users', 'abc123');
oneUser.get()// GET /users/abc123
.then(function(user) {
user.getList('inboxes'); // GET /users/abc123/inboxes
});
还可以通过
allUrl()
和oneUrl()
指定请求的URL
可以使用getList()
来获取所有信息,getList()
方法返回了一个集合,12博体育,其中包含了可以用来操作特定集合的方法
Restangular返回增强过的promise对象,我们可以调用promise对象上的方法,还可以调用一些特殊的方法,比如$object
。$object
会立即返回一个空数组(或对象),在服务器返回信息后,数组会被用新的数据填充:
messages.post(newMessage).then(function(newMsg) {
$scope.messages = messages.getList().$object;
}, function(errorReason)
// 出现了一个错误
});
注意,在修改一个对象之前对其进行复制,然后对复制的对象进行修改和保存是一个好做法。Restangular有自己的复制版本,因此无需对一系列方法重新进行绑定。在更新对象时使用Restangular.copy()是一个比较好的实践。
Restangular支持所有的HTTP方法:
.get()
和.getList('books')
.put()
.post()
.remove()
.head()
.trace()
.options()
.patch()
可以传入参数和头对象:
var queryParamObj = {
role: 'admin'
},
headerObj = {
'x-user': 'admin'
};
messages.getList('accounts', queryParamObj, headerObj);
将RestangularProvider注入到.config()
函数中,或者将Restangular注入到一个.run()
函数中,对Restangular进行设置
通过.setBaseUrl()
方法给所有后端 API 请求设置 baseUrl
angular.module('myApp', ['restangular'])
.config(function(RestangularProvider) {
RestangularProvider.setBaseUrl('/api/v1');
});
使用elementTransformers
可以在Restangular对象被加载后为其添加自定义方法
angular.module('myApp', ['restangular'])
.config(function(RestangularProvider) {
RestangularProvider.addElementTransformer('authors', false, function(element) {
element.fetchedAt = new Date();
return element;
});
});
还可以对已有数据模型或集合进行扩展:
angular.module('myApp', ['restangular'])
.config(function(RestangularProvider) {
RestangularProvider.extendModel('authors', function(element) {
element.getFullName = function() {
return element.name + ' ' + element.lastName;
};
return element;
});
});
Restangular可以设置响应拦截器。responseInterceptors
在每个响应从服务器返回时被调用。调用时会传入以下参数:
angular.module('myApp', ['restangular'])
.config(function(RestangularProvider) {
RestangularProvider.setResponseInterceptor(function(data, operation, what) {
//getList方法应当始终返回数组
if (operation == 'getList') {
var list = data[what];
list.metadata = data.metadata;
return list;
}
return data;
});
});
getList方法应当始终返回数组
requestInterceptors
在将数据实际发送给服务器之前对其进行操作。使用setRequestInterceptor()
来设置requestInterceptor。这个方法可以接受下面四个参数:
angular.module('myApp', ['restangular'])
.config(function(RestangularProvider) {
RestangularProvider.setRequestInterceptor(function(elem, operation, what) {
if (operation === 'put') {
elem._id = undefined;
return elem;
}
return elem;
});
});
Restangular支持自定义字段,可以通过.setRestangularFields()
方法来自定义:
angular.module('myApp', ['restangular'])
.config(function(RestangularProvider) {
RestangularProvider.setRestangularFields({
id: '_id.$oid'
});
});
通过设置错误拦截器可以捕获Restangular内的错误。通过errorInterceptor
可以将错误信息在应用中进行传递
angular.module('myApp', ['restangular'])
.config(function(RestangularProvider) {
RestangularProvider.setErrorInterceptor(function(resp) {
displayError();
return false; // 停止promise链
});
});
如果我们想加载一个没有嵌套在其他资源中的资源,可以使用.setParentless()
设置告诉Restangular不要构造嵌套结构的URL
angular.module('myApp', ['restangular'])
.config(function(RestangularProvider) {
RestangularProvider.setParentless(['cars']);
});
.setParentless()
接受两种类型的参数:
在实践中,只通过一个切入点(主URL)来同后端服务器进行通信是非常好的做法,其他数据模型通过链接来指向相关联的资源。 Restangular通过selfLink
、oneUrl
和allUrl
来支持这个有用的做法。
强烈建议将Restangular封装在一个自定义服务对象内