使用 Angular 的 $resource 保存子资源

Saving subresource with Angular's $resource

我定义了一个工厂 returns a $resource:

myApp.factory('Region', function($resource) {
    return $resource(baseUrl + '/templates/:templateId/regions/:regionId', null, {
        query: {
            method: 'GET',
            isArray: false
        },
        update: {
            method: 'PUT'
        }
    });
});

如您所见,区域是模板的子资源,我将端点定义为/templates/:templateId/regions/:regionId

当我想保存一个新区域时,我的问题就来了。如何指定 templateId 保存区域?这是我的片段:

$scope.save = function() {
    if ($scope.mode === 'edit') {
        // TODO
    } else {
        Region.save($scope.region, function(success) {
            $state.go('app.templateList')
        });
    }
};

在我拥有的所有其他资源中,我刚刚使用了 Model.save($scope.model);,我不知道如何指定其他 URL 参数,Angular 文档似乎也没有盖上。

根据the docs,非 GET(例如 PUT)方法接受以下参数

Resource.save([parameters], postData, [success], [error]).

其中 parameters 是一个路径参数,它是可选的,postData – 请求的主体。如果您想提供 templateId,只需将其添加为第一个参数:

Region.save({templateId: 'id'}, $scope.region, function(success) {
    $state.go('app.templateList')
});

我遇到过类似的困境。我考虑了一些通用约定,在哪里创建子资源 X 例如作为某个资源 Y 拥有的集合的新元素我会做

POST /api/Y/<yId>/X

然后访问 Y 拥有的 X 集合:

GET /api/Y/<yId>/X

然而,对于修改或删除子资源,我们可以直接访问子资源:

PUT /api/X/<xId>
DELETE /api/X/<xId>

为了实现上述目标,我们可以使用 $resource 定义为

Subresource = $resource('/api/:parent/:parentId/subresource/:id', 
  { id: '@id' }, 
  {
    'update': { method:'PUT' } // this is because Angular lacks PUT support
  });

那我们就可以像

一样使用它
var subresourceList;
Subresource.query({parent: 'Y', parentId: parentId }, 
  function(result) {
    // handle result here
    subresourceList = result;
  });

修改单个子资源对象后,我们可以使用

保存它
var subresource = subresourceList[0];
subresource.someProp = 'newValue';
subresource.$update()

对于较早的子资源定义,$update 将 PUT 直接执行到 /api/X/<xId>,这在子资源 X 对象被修改与其拥有的 Y 无关时是合理的。