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

时间:2014-09-19 07:36:40

标签: angularjs

我一直在几个存储库中使用自定义操作。到目前为止,我只需要指定网址和方法。

例如:

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定义中,具有多个路径参数的自定义操作要求使用@符号定义它们。

而不是只有一个。

为什么?

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

2 个答案:

答案 0 :(得分:26)

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

使用'@'(在默认参数或操作参数中)是强制性的。
它是为了方便而提供的,具有特殊的含义。 paramKey: '@someProp'表示:
“对于具有请求主体的方法(例如POST,PUT等),如果我没有为参数paramKey显式提供值,请查看我的数据对象以获取名为{{1}的属性并使用其值作为someProp参数的值。“


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

paramKey

使用实例方法时,实例本身充当数据对象:

SomeResourceClass.save({.../* data object */...});

另请参阅此 short demo


<强>更新

您似乎想要调用以下自定义操作:

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' } 这样调用它并不能按预期工作,因为它将(预期)params对象解释为数据对象。

<ResourceClass>.add({teamId: teamId, technicianId: technicianId})文档中,“非GET”方法(如您的)的方法签名是:

  • 非GET“类”操作:Resource.action([parameters],postData,[success],[error])
  • 非GET实例操作:实例。$ action([参数],[成功],[错误])

从上面的内容可以看出,如果你只在“class”动作调用中传递一个对象,那么它将被解释为ngResource对象(请求的有效负载)。此外,如果您有data - 前缀默认参数,那么将根据@对象解析URL参数(这就是它使用默认参数的原因)。


为了让Angular将data对象解释为params(而不是params对象),并且因为data param是必需的,所以你需要调用它像这样:

data

(或者,您可以使用<ResourceClass>.add({teamId: teamId, technicianId: technicianId}, {}) 实例,但这是另一个故事。)

答案 1 :(得分:3)

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

$resource(url, [paramDefaults], [actions]);

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

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

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

相关问题