使用Restangular解析客户端上的对象依赖性

时间:2014-08-08 08:32:05

标签: angularjs rest angularjs-ng-repeat spring-data restangular

在使用Restangular通过REST检索实体关系后,我在(AngularJS)客户端恢复实体关系时遇到问题。我搜索了很多,但找不到一个干净的解决方案。我有几年的编程经验,但我对AngularJS生态圈和REST范例都很陌生。

任务

在我的Spring Data后端,我有两个实体ArticleArticleGroup,处于1:n关系。生成的REST json(通过Spring Data Rest)看起来像这样:

文章

{
"_embedded": {
    "articles": [
        {
            "id": 1,
            "name": "A Drink",
            "price": 2.90,
            "created": null,
            "modified": null,
            "active": false,
            "displayOrder": 0,
            "_links": {
                "self": {
                    "href": "http://localhost:8080/articles/1"
                },
                "articleGroup": {
                    "href": "http://localhost:8080/articles/1/articleGroup"
                }
            }
        },
      ...

ArticleGroup

{
"_embedded": {
    "articleGroups": [
        {
            "id": 1,
            "name": "Drinks",
            "printer": null,
            "_links": {
                "self": {
                    "href": "http://localhost:8080/articleGroups/1"
                },
                "articles": {
                    "href": "http://localhost:8080/articleGroups/1/articles"
                }
            }
        },
      ...

现在我想显示一个包含articleGroup.name的标签组作为标签的标签,并显示本文章中的文章表作为其内容:

<tabset>
        <tab ng-repeat="group in articleGroups" heading="{{group.name}}">
            <table class="table">
                <tr ng-repeat="article in group.articles">
                    <td ng-click="increase(article)">{{article.name}}</td>
                    <td>{{article.price | currency }}</td>
                    ...
                </tr>
            </table>
        </tab>
</tabset>

我使用Restangular:

在我的AngularJS控制器中轻松检索articleGroups
Restangular.all('articleGroups').getList()
        .then(function(groups) {
            $scope.articleGroups = groups;
        });

这很好用,标签显示得很好。现在我也可以为这些文章这样做,但是在这里我遇到了几天来我正在处理的问题。

问题

如何过滤articleGroup的文章,以便文章的每一部分都显示在右边的标签中?上面的ng-repeat中的正确表达式是什么,我只是放了“group.articles”现在作为占位符? 这听起来很容易,但我的问题是我没有文章的articleGroup的操作标识来过滤每个标签的ng-repeat中的正确文章。我尝试了什么:

  • 使用self.href作为id {la} article._links.articleGroup.href == articleGroup._links.self.href,但这不起作用,因为您可以在上面的JSON中看到这两个链接设置不同
  • 将(数据库)id添加到JSON,但当然一篇文章不包含其articleGroup的id,而只包含链接关系
  • 循环遍历articleGroups并将articleGroup.id作为键检索每个组的文章到一个数组中,但是我无法通过JavaScript或无限循环获得undefined错误来解决这个问题

帮助

在我继续摆弄几个小时之前,如果你能给我一个关于采取哪个方向的提示以及对任务的“干净”和方法上合理的方法,那将是很好的。我怎样才能将文章及其相应的群体带回来? 这似乎是一个容易(和频繁)的问题,但我试了好几个小时和几天让它运行,并担心我错过了什么。我看了很多例子,但没有一个帮助我取得突破。 我很乐意根据需要提供任何进一步的信息。非常感谢提前!

1 个答案:

答案 0 :(得分:0)

好吧,我解决了。事实证明,我在处理异步请求时迷失了方向,特别是在拥有数据对象本身和请求的承诺之间,即在可用时尽快提供对数据的访问的占位符 - 在{{3 }}

Restangular总是返回promises。所以我提出了以下解决方案,它完全符合我的要求:

对于控制器代码:

Restangular.all('articleGroups').getList()
        .then(function(groups) {
            $scope.articleGroups = groups;
            for(i=0;i<groups.length;i++) {
                $scope.articles[groups[i].id] = groups[i].getList("articles")
            }
        });

因此当articleGroups从服务器到达时,我会遍历所有这些内容并将它们放入数组$scope.articles中,并以articleGroup.id为键。请注意,group[i].getList("articles")返回文章关系的承诺。使用Restangular的$ object属性,我收到了ng-repeat中的文章数据数组:

    <tabset>
        <tab ng-repeat="group in articleGroups" heading="{{group.name}}">
            <table class="table">
                <tr ng-repeat="article in articles[group.id].$object | orderBy:'id':false ">
                    <td>{{article.name}}</td>
                    <td>{{article.price | currency }}</td>
                </tr>
            </table>
        </tab>
    </tabset>

现在,所选articleGroup标签的所有文章都会显示在标签上。虽然这看起来很好,但我仍然不确定这是否是风格或性能方面的最佳解决方案。但至少它领先一步。评论非常欢迎。