我想从我的API请求资源时发送身份验证令牌。
我确实使用$ resource实现了服务:
factory('Todo', ['$resource', function($resource) { return $resource('http://localhost:port/todos.json', {port:":3001"} , { query: {method: 'GET', isArray: true} }); }])
我有一个存储身份验证令牌的服务:
factory('TokenHandler', function() { var tokenHandler = {}; var token = "none"; tokenHandler.set = function( newToken ) { token = newToken; }; tokenHandler.get = function() { return token; }; return tokenHandler; });
我想tokenHandler.get通过Todo服务发送的每个请求都发送令牌。通过将其放入特定动作的调用中,我能够发送它。例如,这有效:
tokenHandler.get
Todo
Todo.query( {access_token : tokenHandler.get()} );
但是我宁愿将access_token定义为Todo服务中的参数,因为它必须随每个调用一起发送。并提高干度。但是工厂中的所有内容仅执行一次,因此access_token在定义工厂之前必须是可用的,此后不能更改。
有没有办法将动态更新的请求参数放入服务中?
感谢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()方法将资源覆盖,该方法将资源和一系列操作作为参数。
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()以为每个操作调用另一个函数。最后,它返回修改后的资源副本。
wrapActions()
actions
tokenWrapper()
该tokenWrapper方法首先创建一个预先存在的资源操作的副本。该副本下划线。如此query()成为_query()。之后,新方法将覆盖原始query()方法。_query()正如Andy Joslin所建议的那样,此新方法将包装以为通过该操作发送的每个请求提供auth令牌。
tokenWrapper
query()
_query()
这种方法的好处是,我们仍然可以使用每个angularjs资源(获取,查询,保存等)附带的预定义操作,而不必重新定义它们。在其余代码中(例如在控制器内),我们可以使用默认操作名称。