我一直在一些存储库中使用自定义操作。到目前为止,我只需要指定url和方法。
例如:
updatePassword: { url: ENV.NITRO_PROJECT_REST_URL + '/admins/:adminId/password', method: 'PUT' }
但是随后,我不得不编写一个自定义操作,该操作不包含一个,而是两个路径参数:
technicianModule.controller('technician.teamCtrl', ['$scope', '$state', '$stateParams', 'CommonService', 'TechnicianService', 'TeamService', 'TeamTechnicianService', function($scope, $state, $stateParams, CommonService, TechnicianService, TeamService, TeamTechnicianService) { $scope.add = function(teamId) { TeamTechnicianService.add(teamId, $stateParams.technicianId, function() { TeamService.get(teamId, function(data) { $scope.teams.push(data); $scope.unassignedTeams.splice(CommonService.getResourceIndex($scope.unassignedTeams, data), 1); }); }); }; } ]); teamModule.factory('TeamTechnicianService', ['RESTService', function(RESTService) { var factory = {}; factory.add = function(teamId, technicianId, callback) { return RESTService.TeamTechnician.add({teamId: teamId, technicianId: technicianId}).$promise.then(callback); } return factory; } ]);
所以我首先将其编码为:
TeamTechnician: $resource(ENV.NITRO_PROJECT_REST_URL + '/teamtechnicians/:teamtechnicianId', {}, { add: { url: ENV.NITRO_PROJECT_REST_URL + '/teamtechnicians/:teamId/:technicianId', method: 'POST' }
但这是行不通的。参数未传递。
经过几次尝试,我发现在自定义操作定义之前添加一些参数定义可以正常工作。
它必须像:
TeamTechnician: $resource(ENV.NITRO_PROJECT_REST_URL + '/teamtechnicians/:teamtechnicianId', { teamId: '@teamId', technicianId: '@technicianId' }, { add: { url: ENV.NITRO_PROJECT_REST_URL + '/teamtechnicians/:teamId/:technicianId', method: 'POST' }
请注意以下情况:
teamId: '@teamId', technicianId: '@technicianId'
当时我的理解是,在$ resource定义中,具有多个路径参数的自定义操作要求使用@符号定义它们。
当它只有一个时,不是。
这是为什么 ?
为什么不能在自定义操作中而不是在资源中声明路径参数?
可以 根据每个自定义操作声明参数。 默认参数的名称含义是:默认参数(如:“在未提供其他参数的情况下使用”)。
使用的'@'(无论是在默认参数或在动作参数)是 不 必需的。 它是为方便起见而提供的,具有特殊含义。paramKey: '@someProp'意思是: “对于具有请求正文的方法(例如POST,PUT等),如果我未明确提供参数值paramKey,请在我的数据对象中查找名为的属性,someProp并将其值用作paramKey参数值”。
'@'
paramKey: '@someProp'
paramKey
someProp
请注意,使用类方法时,必须显式提供数据对象:
SomeResourceClass.save({.../* data object */...});
当使用实例方法时,实例本身充当数据对象:
var instance = SomeResourceClass.get(...); instance.$save(); /* `instance` will act as the data object. */
另请参 见此简短演示 。
更新:
似乎您想调用以下自定义操作:
add: { url: ENV.NITRO_PROJECT_REST_URL + '/teamtechnicians/:teamId/:technicianId', method: 'POST' }
像这样尝试调用它<ResourceClass>.add({teamId: teamId, technicianId: technicianId})无法按预期方式工作,因为它将(预期为)params对象解释为数据对象。
<ResourceClass>.add({teamId: teamId, technicianId: technicianId})
从ngResource文档中,“非GET”方法(如您的方法)的方法签名为:
ngResource
从上面的摘录中可以明显看出,如果仅在“类”操作调用中传递一个对象,则该data对象将被解释为对象(请求的有效负载)。另外,如果您具有@-prefixed默认参数,则URL参数将针对该data对象进行解析(这就是它与默认参数一起使用的原因)。
data
@
为了使Angular将params对象解释为一个params(而不是data对象),并且由于data参数是强制性的,因此您需要这样调用它:
params
<ResourceClass>.add({teamId: teamId, technicianId: technicianId}, {})
(或者,您可能正在使用TeamTechnician instance ,但这是另一回事了。)
TeamTechnician