アンディ・ジョスリンに感謝。私は、リソース アクションをラップするという彼のアイデアを選びました。リソースのサービスは次のようになります。
.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()
その後、リソースとアクションの配列をパラメーターとして受け取るメソッドの戻りによって、リソースが上書きされます。
ご想像のとおり、後者のメソッドは実際にはアクションをラップして、すべてのリクエストに認証トークンを含め、変更されたリソースを返します。それでは、そのためのコードを見てみましょう。
.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 が提案したように、この新しいメソッドは wrapsし、そのアクションを介して送信されるすべてのリクエストに認証トークンを提供します。
このアプローチの良い点は、すべての angularjs リソース (get、query、save など) に付属する定義済みのアクションを再定義することなく使用できることです。コードの残りの部分 (コントローラー内など) では、デフォルトのアクション名を使用できます。