如何使用AngularJS$资源自定义操作?

如何使用AngularJS$资源自定义操作?,angularjs,Angularjs,我在一些存储库中使用了自定义操作。到目前为止,我只需要指定url和方法 例如: updatePassword: { url: ENV.NITRO_PROJECT_REST_URL + '/admins/:adminId/password', method: 'PUT' } 但是,我必须编写一个自定义操作,该操作不是一个而是两个路径参数: technicianModule.controller('technician.teamCtrl', ['$scope', '$state', '

我在一些存储库中使用了自定义操作。到目前为止,我只需要指定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定义中,具有多个路径参数的自定义操作需要使用@符号定义它们

而不是当它只有一个

为什么呢


为什么不能在自定义操作中而不是在资源中声明路径参数?

定义$resource时,定义如下所示

$resource(url、[paramdaults]、[actions])

第二个参数
paramDefaults
仅用于提供默认值。
@
语法用于从PUT或POST请求的有效负载派生参数值

在实际调用资源操作时,始终可以提供参数值。如果没有,则采用默认参数值,如果没有,则删除片段

可以参数化的内容需要使用
语法在$resource上定义,默认值也是如此。 对于操作方法,它们只采用相同的
$http config
对象。

可以为每个自定义操作声明参数
默认参数是其名称所暗示的:默认参数(如:“在未提供其他参数的情况下使用”)

@'
(在默认参数或动作参数中)的使用是而不是强制的。
它是为了方便而提供的,具有特殊的意义<代码>参数键:“@someProp”
的意思是:
“对于具有请求正文的方法(例如POST、PUT等),如果我没有明确为参数
paramKey
提供值,请查看名为
someProp
的属性的数据对象,并将其值用作
paramKey
参数的值。”


请注意,使用类方法时,必须显式提供数据对象:

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'
}
尝试这样调用它
.add({teamId:teamId,technicianId:technicianId})
无法按预期工作,因为它将(预期的)params对象解释为数据对象

ngResource
文档中,非GET方法(如您的方法)的方法签名如下:

  • 非获取“类”操作:Resource.action([parameters]、postData、[success]、[error])
  • 非获取实例操作:实例.$action([参数],[成功],[错误])
从上面的练习中可以清楚地看出,如果在“类”操作调用中只传递一个对象,那么它将被解释为
数据
对象(请求的有效负载)。此外,如果您有
@
-前缀的默认参数,那么URL参数将针对该
数据
对象进行解析(这就是它使用默认参数的原因)


为了使Angular将
params
对象解释为
params
(而不是
data
对象),并且由于
data
param是必需的,您需要这样调用它:

<ResourceClass>.add({teamId: teamId, technicianId: technicianId}, {})
.add({teamId:teamId,technicianId:technicianId},{})

(或者,您可以使用
TeamTechnician
实例,但这是另一回事。)

您对默认参数的解释比官方文档更有用。好的,每个自定义操作都可以声明参数。但是为什么我的POST需要参数,而不是PUT点需要参数呢?@Stephaneybert:POST和PUT方法的句柄是相同的,所以应该没有任何区别。你能给我一把小提琴或至少一把小提琴,让我重现你面临的问题吗?(顺便说一句,如果这个答案有助于你不要忘记投票和/或接受。)@Stephaneybert:我对类似问题的这一评论可能会对默认参数/action params/'@'-前缀参数的情况有所帮助:感谢这些好的解释。你们真是太好了。但我仍然有我的原始问题。谢谢,但我的原始问题是为什么我的PUT自定义操作不需要任何路径参数,而我的POST自定义操作需要它们。这就是调用方法和传递参数的方式。如果未传递参数,则传递paramDefaults中的默认值。我不需要默认值。我确实传递参数。只是,这些都看不到。我最初的问题是,我只使用了默认参数,因为事情突然发生了变化。不是出于设计或选择。我将尝试在网上做一个例子。