![](/img/trans.png)
[英]Restangular addElementTransformer / extendModel for ALL routes
[英]Custom (OData) routes in Restangular
在服務器端,我將Web API與OData路由約定一起使用,這意味着我獲取單個實體的路線如下所示:
/api/v1/Products(1)
而不是:
/api/v1/Products/1
通常,在Restangular中,我將能夠獲得具有以下內容的單個實體:
Restangular.one('Product', 1);
但這不適用於我的OData端點。 我看過customGET
和setRequestInterceptor
但似乎找不到示例或弄清楚如何更改路由以匹配我的端點。 最好在全球范圍內使用,因為我的所有實體都將采用這種相同的格式。
任何幫助是極大的贊賞。
Restangular文檔詳細介紹了如何創建自定義配置,您可以通過編輯源代碼restangular.js來執行此操作,但是此可擴展性點使我們能夠保持整潔的實現,該實現應與大多數定制或RestAngular的未來版本兼容,並且允許並行標准REST API和OData v4 API。
// Global configuration
app.config(function(RestangularProvider) {
RestangularProvider.setBaseUrl('http://localhost:16486');
RestangularProvider.setRestangularFields({ id: 'Id' });
});
// Restangular service targeting OData v4 on a the specified route
app.factory('ODataRestangular', function(Restangular) {
return Restangular.withConfig(function(RestangularConfigurer) {
RestangularConfigurer.setBaseUrl(RestangularConfigurer.baseUrl + '/odata');
// OData v4 controller(key) Item Route convention
RestangularConfigurer.urlCreatorFactory.path.prototype.base = function(current) {
var __this = this;
return _.reduce(this.parentsArray(current), function(acum, elem) {
var elemUrl;
var elemSelfLink = RestangularConfigurer.getUrlFromElem(elem);
if (elemSelfLink) {
if (RestangularConfigurer.isAbsoluteUrl(elemSelfLink)) {
return elemSelfLink;
} else {
elemUrl = elemSelfLink;
}
} else {
elemUrl = elem[RestangularConfigurer.restangularFields.route];
if (elem[RestangularConfigurer.restangularFields.restangularCollection]) {
var ids = elem[RestangularConfigurer.restangularFields.ids];
if (ids) {
// Crude Implementation of 'several', don't try this with more than
// 60 Ids, performance degrades exponentially for large lists of ids.
elemUrl += '?$filter=((Id eq ' + ids.join(')or(Id eq ') + '))';
}
} else {
var elemId;
if (RestangularConfigurer.useCannonicalId) {
elemId = RestangularConfigurer.getCannonicalIdFromElem(elem);
} else {
elemId = RestangularConfigurer.getIdFromElem(elem);
}
if (RestangularConfigurer.isValidId(elemId) && !elem.singleOne) {
elemUrl += '(' + (RestangularConfigurer.encodeIds ? encodeURIComponent(elemId) : elemId) + ')';
}
}
}
acum = acum.replace(/\/$/, '') + '/' + elemUrl;
return __this.normalizeUrl(acum);
}, RestangularConfigurer.baseUrl);
};
// add a response interceptor for OData v4:
RestangularConfigurer.addResponseInterceptor(function(data, operation, what, url, response, deferred) {
var extractedData;
// Collection requests are 'getList' operations
if (operation === "getList") {
// return the value array
extractedData = data.value;
} else {
// return the first item in the array
if(data.value.length > 0)
extractedData = data.value[0];
}
// pass the metadata back
if(extractedData) {
extractedData.meta = { context: data['@odata.context'] };
if(data['@odata.count'])
extractedData.meta.count = data['@odata.count'];
}
return extractedData;
});
});
});
實施示例:
// Controller for list route
function ListCtrl($scope, ODataRestangular) {
$scope.providers = ODataRestangular.all("providers").getList({ $count:true }).$object;
$scope.some = ODataRestangular.several("providers", 15,16,17,18).getList();
$scope.single = ODataRestangular.one("providers", 15).get();
}
從網絡流量中捕獲的URL:
http://localhost:16486/odata/providers?$count=true
http://localhost:16486/odata/providers?$filter=((Id eq 15)or(Id eq 16)or(Id eq 17)or(Id eq 18))
http://localhost:16486/odata/providers(15)
我一直努力嘗試編寫一個自定義服務工廠,並修改BreezeJS以使其與OData v4一起使用,直到最近才偶然發現Restangular,現在我真的很欣賞進入restangular的可擴展設計,因為通常缺少文檔化的客戶端框架支持阿基里斯之heel阻止了OData v4的廣泛采用。 我希望這個答案有助於使更多的開發人員使用版本4。
Restangular不明確支持OData API。 您可以使基礎工作正常,但是最好使用支持查詢OData API的庫,例如breeze.js 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.