簡體   English   中英

自定義(OData)路線在Restangular中

[英]Custom (OData) routes in Restangular

在服務器端,我將Web API與OData路由約定一起使用,這意味着我獲取單個實體的路線如下所示:

/api/v1/Products(1)

而不是:

/api/v1/Products/1

通常,在Restangular中,我將能夠獲得具有以下內容的單個實體:

Restangular.one('Product', 1);

但這不適用於我的OData端點。 我看過customGETsetRequestInterceptor但似乎找不到示例或弄清楚如何更改路由以匹配我的端點。 最好在全球范圍內使用,因為我的所有實體都將采用這種相同的格式。

任何幫助是極大的贊賞。

Restangular文檔詳細介紹了如何創建自定義配置,您可以通過編輯源代碼restangular.js來執行此操作,但是此可擴展性點使我們能夠保持整潔的實現,該實現應與大多數定制或RestAngular的未來版本兼容,並且允許並行標准REST API和OData v4 API。

如何使用與全局配置不同的配置創建Restangular服務

// 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM