Динамические заголовки ресурсов
Я хотел бы иметь сервис, предоставляющий ресурс, как в следующем коде:
angular.module('myApp.userService', ['ngResource'])
.factory('UserService', function ($resource)
{
var user = $resource('/api/user', {},
{
connect: { method: 'POST', params: {}, isArray:false }
});
return user;
}
Затем при использовании действия connect
я хотел бы динамически передать HTTP-заголовок, что означает, что он может измениться для каждого вызова. Вот пример, в контроллере, пожалуйста, см. Комментарий в коде:
$scope.user = UserService;
$scope.connect = function ( user )
{
var hash = 'Basic ' + Base64Service.encode(user.login + ':' + user.password);
// I would like this header to be computed
// and used by the user resource
// each time I call this function
$scope.user.headers = [{Authorization: hash}];
$scope.user.connect( {},
function()
{
// successful login
$location.path('/connected');
}
,function()
{
console.log('There was an error, please try again');
});
}
Знаете ли вы способ сделать это, либо напрямую, либо с помощью трюка?
Заключительные мысли
Принятый ответ не полностью отвечает на вопрос, поскольку заголовки не являются полностью динамическими, поскольку factory возвращает фактически factory (!), что не соответствует моему коду.
Поскольку $resource является factory, нет возможности сделать его динамическим.
Я, наконец, уничтожаю объект ресурса каждый раз, когда пользователь подключается. Таким образом, у меня есть ресурс с заголовком, вычисленным, когда пользователь подключается.
Решение, предоставленное @Stewie, полезно для этого, поэтому я сохраняю его как принятое.
Вот как я сделал соединение, которое можно использовать несколько раз, когда ресурс уничтожается/воссоздается, когда (повторное) соединение:
this.connect = function (user)
{
self.hash = 'Basic ' + Base64Service.encode(user.login + ':' + user.password);
console.log("CONNECT login:" + user.login + " - pwd:" + user.password + " - hash:" + self.hash);
if (self.userResource)
{
delete self.userResource;
}
self.userResource = $resource('/api/user/login', {}, {
connect: {
method: 'POST',
params: {},
isArray: false,
headers: { Authorization: self.hash }
}
});
var deferred = $q.defer();
self.userResource.connect(user,
function (data)
{
//console.log('--------- user logged in ----- ' + JSON.stringify(data));
// successful login
if (!!self.user)
{
angular.copy(data, self.user);
}
else
{
self.user = data;
}
self.setConnected();
storage.set('user', self);
deferred.resolve(self);
},
function (error)
{
self.user = {};
self.isLogged = false;
storage.set('user', self);
deferred.reject(error);
}
);
return deferred.promise;
};
Ответы
Ответ 1
Начиная с angularjs v1.1.1 и ngResource v.1.1.1, это можно выполнить, используя свойство headers
объекта действия $resource
.
Вы можете обернуть свой ресурс в функцию, которая принимает пользовательские заголовки в качестве параметра и возвращает объект $resource
с вашими настраиваемыми заголовками, установленными в соответствующих определениях действий:
PLUNKER
var app = angular.module('plunker', ['ngResource']);
app.controller('AppController',
[
'$scope',
'UserService',
function($scope, UserService) {
$scope.user = {login: '[email protected]', password: '123'};
$scope.connect = function() {
// dropping out base64 encoding here, for simplicity
var hash = 'Basic ' + $scope.user.login + ':' + $scope.user.password;
$scope.user.headers = [{Authorization: hash}];
UserService({Authorization: hash}).connect(
function () {
$location.url('/connected');
},
function () {
console.log('There was an error, please try again');
}
);
};
}
]
);
app.factory('UserService', function ($resource) {
return function(customHeaders){
return $resource('/api/user', {}, {
connect: {
method: 'POST',
params: {},
isArray: false,
headers: customHeaders || {}
}
});
};
});
Ответ 2
Я установил свои услуги немного по-другому.
angular.module('MyApp').factory('UserService',function($resource, localStorageService) {
var userResource = function(headers) {
return $resource("api/user", {},
{
get: {
method: 'GET',
headers: headers
},
create: {
method: 'POST',
headers: headers
}
}
);
};
return {
api: userResource,
get: function(userid){
var service = this;
return service.api({"token": "SomeToken"}).get({userid: userid}, function (data){
return data;
});
},
create: function(user){
var service = this;
return service.api({"token": localStorageService.get("token")}).create({user: user}, function (data){
return data;
});
}
};
});