AngularJS:具有嵌套资源的 $resource
Posted
技术标签:
【中文标题】AngularJS:具有嵌套资源的 $resource【英文标题】:AngularJS: $resource with nested resources 【发布时间】:2014-11-14 10:52:51 【问题描述】:我正在将 AngularJS $resource 模型用于 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);
);
【问题讨论】:
【参考方案1】:您可以使用 AngularJS $resource
定义轻松访问嵌套的 RESTful 资源。
线索是了解$resource 定义中每个action 定义(在actions
列表中)的params
参数如何工作。正如文档所说,这是一个
此操作的可选预绑定参数集。 […]
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/
请求。
但是,鉴于 $resource
URL ('books/:id/:subResource'
) 的新 :subResource
部分,您现在可以生成一个
GET books/42/comments
通过调用 either Book.get( id: 42, subResource: 'comments' )
或定义为您的 comments
操作的更简洁优雅的界面 Book.comments( id: 42 )
来请求。
【讨论】:
我知道我回答得这么晚了,但是如果答案对你有用,那么如果你接受它作为答案会很棒——这样其他用户就可以从知道答案有效的过程中受益。如果您有任何问题,请告诉我。 这个解决方案的问题是返回的 cmets 将是 Book 资源的实例。所以如果我们调用Book.comments( id: 42 ).$promise.then(function (comments) comments[0].$get(); );
那么这个$get
会尝试调用GET /books/<commend_id>
这当然是不对的。
djxak,你有解决这个问题的方法吗?【参考方案2】:
据我所知,你不能嵌套资源,但是做你正在寻找的东西非常简单:
您可以定义可以在每个资源中覆盖的可选参数(如 category
此处),甚至覆盖 url(查看 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'
);
]);
【讨论】:
【参考方案3】:您可能希望使用 Restangular,因为它可以处理嵌套资源并且是一种干净且简单的方法。
【讨论】:
【参考方案4】:正如 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 初始化代码。不过,这似乎有点不便。
【讨论】:
以上是关于AngularJS:具有嵌套资源的 $resource的主要内容,如果未能解决你的问题,请参考以下文章
spring配置加载maven项目里面的src/main/resoures下的静态资源,配置路径是file:
具有嵌套资源的 AFRESTClient pathForEntity?