AngularJS:具有嵌套资源的$ resource

时间:2014-11-14 10:52:52

标签: angularjs rest restful-url

我将AngularJS $资源模型用于REST API。我有这样的事情:

angular.module('libraryapp')
    .factory('Book', function($resource){
        return $resource('books/:id');
    });

我正在以这种方式使用:

Book.get({ id: 42 }, function(book) {
    console.log(book);
});

但我也想要一个端点到子资源,让我们说:

GET /books/:id/comments

我应该如何在模块中定义它?我可以用某种方式扩展Book,像这样使用它

Book.get({ id: 42 }).Comment.query(function(comments) {
    console.log(comments);
});

4 个答案:

答案 0 :(得分:7)

您可以使用AngularJS $resource定义轻松访问嵌套的RESTful资源。

线索是了解$resource定义中每个操作定义的params参数(在actions列表中)的工作原理。正如文档所说,它是

  

此操作的可选预绑定参数集。 [...]

angular.module('libraryApp').factory('Book', [
  '$resource', function($resource) {
    return $resource('books/:id/:subResource', {}, {
      comments: {  // The `comments` action definition:
        params: {subResource: 'comments'},
        method: 'GET'
      }
    });
  }
]);

鉴于上述定义,您仍然可以像以前一样使用Book。例如,Book.get({ id: 42 })会转换为GET books/42/请求。

但是,鉴于:subResource网址($resource)的新'books/:id/:subResource'部分,您现在可以生成

GET books/42/comments

请致电 Book.get({ id: 42, subResource: 'comments' })或更短且更优雅的界面Book.comments({ id: 42 })定义为comments行动。

答案 1 :(得分:2)

据我所知,你无法嵌套资源,但要做你正在寻找的东西很简单:

您可以定义可在每个资源中覆盖的可选参数(例如此处为category),甚至可以覆盖网址(查看otherUrl资源)

angular.module('libraryApp').factory('Book', [
  '$resource', function($resource) {
    return $resource('books/:id/:category', {}, {
      comments: {
        method: 'GET',
        action: 'category'
      },
      otherUrls: {
        method: 'GET',
        url: 'books/:id/admin/:option'
      }
    });
  }
]);

答案 2 :(得分:2)

您可能希望使用Restangular,因为它处理嵌套资源和简洁方法。

答案 3 :(得分:0)

正如djxak所指出的,向资源添加动作意味着返回的值是包含资源的类型,而不是子资源的类型。

我通过使用子资源URL创建新资源并修改包含资源的原型以添加功能来解决了类似的问题:

angular.module('libraryapp')
    .factory('Book', function($resource){
        var bookUrl = 'books/:id',
            Book = $resource(bookUrl),
            BookComment = $resource(bookUrl + /comments");

        Book.prototype.getComments = function () {
            return BookComment.query({id: this.id});
        };

        return $resource('books/:id');
    });

用法变为:

Book.get({ id: 42 }).getComments(function(comments) {
    console.log(comments);
});

我看到的这种方法的唯一缺点是,如果您有一个单独的“注释”资源,可以通过其他URL访问该资源,则必须为替代端点复制$ resource初始化代码。不过,这似乎是一个小麻烦。