感谢Andy Joslin。我选择了他包装资源操作的想法。资源服务现在看起来像这样:
.factory('Todo', ['$resource', 'TokenHandler', function($resource, tokenHandler) { var resource = $resource('http://localhost:port/todos/:id', { port:":3001", id:'@id' }, { update: {method: 'PUT'} }); resource = tokenHandler.wrapActions( resource, ["query", "update"] ); return resource;}])如您所见,资源首先是按常规方式定义的。在我的示例中,这包括一个名为的自定义操作
update。之后,通过返回
tokenHandler.wrapAction()方法将资源覆盖,该方法将资源和一系列操作作为参数。
如您所料,后一种方法实际上包装了操作以在每个请求中包括auth令牌,并返回修改后的资源。因此,让我们看一下代码:
.factory('TokenHandler', function() { var tokenHandler = {}; var token = "none"; tokenHandler.set = function( newToken ) { token = newToken; }; tokenHandler.get = function() { return token; }; // wrap given actions of a resource to send auth token with every // request tokenHandler.wrapActions = function( resource, actions ) { // copy original resource var wrappedResource = resource; for (var i=0; i < actions.length; i++) { tokenWrapper( wrappedResource, actions[i] ); }; // return modified copy of resource return wrappedResource; }; // wraps resource action to send request with auth token var tokenWrapper = function( resource, action ) { // copy original action resource['_' + action] = resource[action]; // create new action wrapping the original and sending token resource[action] = function( data, success, error){ return resource['_' + action]( angular.extend({}, data || {}, {access_token: tokenHandler.get()}), success, error ); }; }; return tokenHandler;});如您所见,该
wrapActions()方法从其参数创建资源的副本,并遍历
actions数组
tokenWrapper()以为每个操作调用另一个函数。最后,它返回修改后的资源副本。
该
tokenWrapper方法首先创建一个预先存在的资源操作的副本。该副本下划线。如此
query()成为
_query()。之后,新方法将覆盖原始
query()方法。
_query()正如Andy
Joslin所建议的那样,此新方法将包装以为通过该操作发送的每个请求提供auth令牌。
这种方法的好处是,我们仍然可以使用每个angularjs资源(获取,查询,保存等)附带的预定义操作,而不必重新定义它们。在其余代码中(例如在控制器内),我们可以使用默认操作名称。



