AngularJS:$resource和嵌套资源

AngularJS:$resource和嵌套资源,angularjs,rest,restful-url,Angularjs,Rest,Restful Url,我使用AngularJS$资源模型来RESTAPI。我有这样的想法: angular.module('libraryapp') .factory('Book', function($resource){ return $resource('books/:id'); }); 我以以下方式使用: Book.get({ id: 42 }, function(book) { console.log(book); }); 但我还需要一个子资源的端点,比如: GE

我使用AngularJS$资源模型来RESTAPI。我有这样的想法:

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.get({ id: 42 }).Comment.query(function(comments) {
    console.log(comments);
});

据我所知,您无法嵌套资源,但要完成所需的工作非常简单:

您可以定义可选参数,您可以在每个资源中覆盖这些参数(如这里的
category
),甚至可以覆盖url(查看
otherUrl
资源)


您可能希望改用Restangular,因为它处理嵌套的资源,而且方法简单明了。

您可以通过AngularJS
$resource
定义轻松访问嵌套的RESTful资源

线索是了解定义中每个动作定义(在动作列表中)的
params
参数是如何工作的。正如文件所说,这是一个

此操作的可选预设参数集。[……]

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

但是,给定
$resource
URL(
'books/:id/:subResource'
)的新
:subResource
部分,您现在可以生成

GET books/42/comments

通过调用
Book.get({id:42,subResource:'comments'})
或更简短、更优雅的接口
Book.comments({id:42})
定义为您的
comments
操作进行请求。

正如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初始化代码。这似乎是一个小小的不便。

我知道我回答得这么晚,但如果答案对您有效,那么您最好接受它作为答案,这样其他用户就可以从知道答案有效中获益。如果您有任何问题,请告诉我。此解决方案的问题是,返回的注释将是图书资源的实例。因此,如果我们调用
Book.comments({id:42})。$promise.then(函数(comments){comments[0].$get();})
那么这个
$get
将尝试
get/books/
,这当然是不对的。djxak,你有其他方法解决这个问题吗?
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);
});