2016-02-12 68 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... 
    } 
})(); 

无论如何,这就是我想出的答案。我希望这有助于你们中的一些人来到这里寻找我正在寻找的东西(并且不容易找到)。

相关问题