2016-02-12 69 views
1

我們很快就會對Angular Style Guide進行重構。指南本身非常好(可以在整個網站上找到稍微修改的內容),但沒有人提及$資源如何適合工廠,或者沒有提到可能被忽略的任何原因。一位指導對use $resource over $http where you can說,但不會將其添加到他們的工廠樣式中:/。

我記得在很多地方閱讀的資源更好,這就是爲什麼我開始使用它,但現在我忘記了爲什麼,並想知道如果這仍然是真的 - 尤其是考慮到這個底部的資源對象帖子。有一些意見(Papas ownagain)關於$ resource(不是?)很好,但這是我重新檢查的另一個問題。

因此,假設我們要使用$ resource並在下面給出這個示例代碼,那麼$ resource適合在哪裏,以便它遵守指南中樣式背後的推理?另外,如果你的答案是「它不會,風格[巧妙]推薦$ http,因爲bla,bla和bla。」,那麼這也會很有用。現在

(function() { 
    'use strict'; 

    angular 
     .module('myModule') 
     .factory('oneService', oneService); 

    predicateService.$inject = ['twoService', 'anotherService']; 

    /* @ngInject */ 
    function oneService(twoService, anotherService) { 
     var service = { 
      doSomething: doSomething, 
      etc: etc 
     }; 

     // pos 1 (it really only works here but can be LONG) 
     // var fancyResource = $resource('/path/to/thing', '...'); 

     // Ideally, this should be kept close to the top, right? 
     return service; 

     // pos 2 (here or below ////// is cleaner, but doesn't work) 
     // var fancyResource = $resource('/path/to/thing', '...'); 

     //////////////// 

     function doSomething() {} 

     // rest of functions here etc... 
    } 
})(); 

,我們使用$資源的唯一的地方(也許這也是不正確的),就像doSomething()方法中。在過去的不同時間點,甚至在我們今天的代碼中的各個地方,fancyResource都由服務公開,並直接從控制器使用:oneService.fancyResource.get()。我認爲這可能是$resource的預期用途,但我不再確定。

另外,考慮一個服務可能會相當大(不要擔心其中一些應該/可以分解爲多個資源;假設這個大小很可能需要資源對象,並且需要很多動詞):

var userResource = $resource(baseApiPath + 'users', {}, { 
    get: { 
     method: 'GET', 
     headers: utilityService.getHeaders('sampling'), 
     isArray: true, 
     transformResponse: function(response){ 
      response = JSON.parse(response); 
      if(response.result){ 
       return response.result.users; 
      } 
      return response; 
     } 
    }, 
    getUserDetails: { 
     method: 'GET', 
     url: baseApiPath+'users/:userId', 
     params: { 
      userId: '@userId' 
     }, 
     headers: utilityService.getHeaders('sampling'), 
     transformResponse: function(response){ 
      response = JSON.parse(response); 
      if(response.result){ 
       return response.result.user; 
      } 
      return response; 
     } 
    }, 
    getUserByRole: { 
     method: 'GET', 
     url: baseApiPath+'users/roles/:roleId', 
     params: { 
      roleId: '@roleId' 
     }, 
     headers: utilityService.getHeaders('sampling'), 
    }, 
    getLoggedInUserData: { 
     method: 'GET', 
     url: baseApiPath + 'users/userData', 
     headers: utilityService.getHeaders('sampling'), 
    }, 
    getGrantedAuth: { 
     method: 'GET', 
     url: baseApiPath+'users/applicationPermissions/userId/:userId/:applicationId/', 
     params: { 
      applicationId: '@applicationId', 
      userId: '@userId' 
     }, 
     headers: utilityService.getHeaders('sampling'), 
    } 
}); 
+0

這個答案(http://stackoverflow.com/a/35212885/2800116)正在幫助我爲什麼$資源可能只是簡單的矯枉過正。考慮它,我甚至不使用它提供的save/update/delete()方法,並且不斷重做路徑。最後一行尤爲重要。無論如何,我仍然想知道$ resource對象在上述工廠類型中的位置。 – coblr

+0

似乎你正在推翻事物以及在當前的方法中創建大量的代碼重複 – charlietfl

回答

1

所以,我想我已經根據一些想法找到了我的答案。

首先,我現在認識到,使用像這樣的$資源是完全不正確的,原因有兩個。首先是我正在創建需要他們自己獨特路徑的其他操作。 $資源的全部要點是使GETPUT,POST,DELETE上的單個 REST資源更容易。我基本上整合了我的資源,因爲它們似乎是統一的。例如,/users/users/roles/:roleId應該是兩個不同的資源(並且可能放入兩個不同的服務以維護單一責任風格)。

第二種使用$ resource錯誤的方式實際上是因爲我沒有真正使用它提供給我的query,savedelete方法。我只是爲我想做的事情創建另一個自定義操作。有時候,這還包括一個唯一的網址,例如/users/:userId/delete,這是因爲API並不總是REST API。 $資源是專門爲兼容REST的API設計的。因爲它封裝了$ http並且可以傳遞參數,所以很容易陷入這個陷阱。 $資源不打算成爲多個$ http使用的配置。

所以,現在,我將如何建議將$資源加入工廠,並且仍然遵循風格指南。

首先,$資源只能與真正的REST API一起使用。一個只有/需要一個路徑的地方,並且只使用/主要是HTTP方法來與它進行交互。另外,因爲工廠的目的是代表和管理一種'東西',與'東西API'交互,每個服務應該只有一個$資源。擴展這個例子,將會有一個用戶服務和一個角色服務;每個都有一個$資源。然後可能會有另一個userRoleService使用它們,並且實際上並沒有自己做任何$ resource資源。無論如何,就是這樣的。

在這種情況下,$ resource配置實際上會比我最初發布的要短得多。由於它更小,我們可以將它看作更像變量聲明並將其放在我們創建的服務對象之上。

(function() { 
    'use strict'; 

    angular 
     .module('myModule') 
     .factory('oneService', oneService); 

    predicateService.$inject = ['anotherService', '$resource']; 

    /* @ngInject */ 
    function oneService(anotherService, $resource) { 

     // this resource is unlikely to get longer than this 
     var userResource = $resource('http://api.com/users/:userId', { 
      userId: '@userId' 
     }); 

     // and we're still able to see all bindables at the top 
     var service = { 
      doSomething: doSomething, 
      etc: etc 
     }; 
     return service; 

     //////////////// 

     function doSomething() { 
      // and in a service method, we can use the resource like this, 
      userResource.query().$promise 
      .then(function(response){...}) 
     } 

     function doSomethingElse() { 
      // or we could use the $resource in a way that would make 
      // chainable with another .then() in the calling method. 
      var load = userResource.query(); 

      // do some internal stuff when we get the response 
      load.$promise 
      .then(function(response){...}); 

      // then return the $resource object, or load.$promise 
      // so that another .then can be chained afterwards. 
      return load; 
     } 

     // rest of functions here etc... 
    } 
})(); 

無論如何,這就是我想出的答案。我希望這有助於你們中的一些人來到這裏尋找我正在尋找的東西(並且不容易找到)。

相關問題