我将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);
});
答案 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初始化代码。不过,这似乎是一个小麻烦。