我想让服务提供以下代码中的资源:
angular.module('myApp.userService', ['ngResource']) .factory('UserService', function ($resource) { var user = $resource('/api/user', {}, { connect: { method: 'POST', params: {}, isArray:false } }); return user; }
然后,当使用该connect操作时,我想动态传递一个HTTP标头,这意味着它可能随每次调用而改变。这是一个示例,在控制器中,请参见代码中的注释:
connect
$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'); }); }
您知道直接或通过技巧做到这一点的方法吗?
接受的答案不能完全回答问题,因为标头不是完全动态的,因为工厂实际上返回了工厂(!),而我的代码中不是这种情况。
由于$ resource是工厂,因此无法使其动态化。
最终,每次用户连接时,我都会销毁资源对象。这样,当用户连接时,我就可以计算出带有标头的资源。
@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;
};
从angularjs v1.1.1和ngResource v.1.1.1开始,可以使用action对象的headers属性来完成此$resource操作。
headers
$resource
您可以将资源包装在一个函数中,该函数接受自定义标头作为参数,并返回一个$resource对象,该对象的自定义标头设置为适当的操作定义:
[PLUNKER](http://plnkr.co/edit/bdETkJ8UJHdyuyFYvSHM?p=preview)
var app = angular.module('plunker', ['ngResource']); app.controller('AppController', [ '$scope', 'UserService', function($scope, UserService) { $scope.user = {login: 'doe@example.com', 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 || {} } }); }; });