AngularJS - 基于JSON构建动态表格

28
{"name": "John", "age": 30, "city": "New York"}

假设有这样一个 JSON:

{
   "name": "john"
   "colours": [{"id": 1, "name": "green"},{"id": 2, "name": "blue"}]
}

以及两个常规的HTML输入框:

<input type="text" name="name" />
<input type="text" name="color" />
<input type="submit" value="submit" />

我需要建立一个包含所有可能变量的表格,例如:

John green
John blue

这意味着如果用户通过输入继续添加值,将出现新行来构建新变体,例如:

我还需要有可用的ID来处理它,并且当我使用输入添加新值时,例如:"Peter" "Black",我需要动态自动填充ID(颜色ID),就像mysql中的自动递增,结果类似于:

{
  "colours": […...{"id": 3, "name": "black"}]
}

这可能吗?我有哪些选项可以使用angular来完成?我仍然按照jQuery的方式思考,但我想用angular的方式实现。

我看了一下hg-repeat并试着使用它,但我还没有想出如何得到期望的结果,唯一能想到的就是使用嵌套的ng-repeats,但这似乎行不通。

非常感谢提前的帮助,

Guillermo

6个回答

56

我想分享一下目前为止我所用的方法,以节省您的时间。

以下是硬编码标题和动态标题的示例(如果不关心数据结构)。在这两种情况下,我都编写了一些简单的指令:customSort

customSort

.directive("customSort", function() {
    return {
        restrict: 'A',
        transclude: true,    
        scope: {
          order: '=',
          sort: '='
        },
        template : 
          ' <a ng-click="sort_by(order)" style="color: #555555;">'+
          '    <span ng-transclude></span>'+
          '    <i ng-class="selectedCls(order)"></i>'+
          '</a>',
        link: function(scope) {

        // change sorting order
        scope.sort_by = function(newSortingOrder) {       
            var sort = scope.sort;

            if (sort.sortingOrder == newSortingOrder){
                sort.reverse = !sort.reverse;
            }                    

            sort.sortingOrder = newSortingOrder;        
        };


        scope.selectedCls = function(column) {
            if(column == scope.sort.sortingOrder){
                return ('icon-chevron-' + ((scope.sort.reverse) ? 'down' : 'up'));
            }
            else{            
                return'icon-sort' 
            } 
        };      
      }// end link
    }
    });

[静态标头的第一个选项]

我使用了单个ng-repeat

这是一个很好的示例,您可以在Fiddle上查看(请注意,没有使用jQuery库!)

输入图像描述

           <tbody>
                <tr ng-repeat="item in pagedItems[currentPage] | orderBy:sortingOrder:reverse">
                    <td>{{item.id}}</td>
                    <td>{{item.name}}</td>
                    <td>{{item.description}}</td>
                    <td>{{item.field3}}</td>
                    <td>{{item.field4}}</td>
                    <td>{{item.field5}}</td>
                </tr>
            </tbody>

[动态头部的第二种选项]

演示2:Fiddle


HTML

<table class="table table-striped table-condensed table-hover">
            <thead>
                <tr>
                   <th ng-repeat="header in table_headers"  
                     class="{{header.name}}" custom-sort order="header.name" sort="sort"
                    >{{ header.name }}

                        </th> 
                  </tr>
            </thead>
            <tfoot>
                <td colspan="6">
                    <div class="pagination pull-right">
                        <ul>
                            <li ng-class="{disabled: currentPage == 0}">
                                <a href ng-click="prevPage()">« Prev</a>
                            </li>

                            <li ng-repeat="n in range(pagedItems.length, currentPage, currentPage + gap) "
                                ng-class="{active: n == currentPage}"
                            ng-click="setPage()">
                                <a href ng-bind="n + 1">1</a>
                            </li>

                            <li ng-class="{disabled: (currentPage) == pagedItems.length - 1}">
                                <a href ng-click="nextPage()">Next »</a>
                            </li>
                        </ul>
                    </div>
                </td>
            </tfoot>
            <pre>pagedItems.length: {{pagedItems.length|json}}</pre>
            <pre>currentPage: {{currentPage|json}}</pre>
            <pre>currentPage: {{sort|json}}</pre>
            <tbody>

                <tr ng-repeat="item in pagedItems[currentPage] | orderBy:sort.sortingOrder:sort.reverse">
                     <td ng-repeat="val in item" ng-bind-html-unsafe="item[table_headers[$index].name]"></td>
                </tr>
            </tbody>
        </table>

顺带一提:

ng-bind-html-unsafe已被弃用,因此我仅在Demo(第二个示例)中使用它。欢迎您进行编辑。


你能提供一个完整的动态头部的第二个实时示例吗? :) - Rovdjuret
@devH 感谢您的评论。我用两个可行的例子彻底改变了我的答案。 - Maxim Shoustin
同样感谢,非常感谢你的回答,非常有启发性。 - DevMoutarde

11

2

TGrid 是另一个在谷歌搜索中通常被忽略的选项。如果您找到的其他网格不符合您的需求,可以尝试一下它,而且是免费的。


谢谢!我终于自己建立了一些东西。再次感谢 :) - Guillermo

1
<table class="table table-striped table-condensed table-hover">
    <thead>
    <tr>
        <th ng-repeat="header in headers | filter:headerFilter | orderBy:headerOrder" width="{{header.width}}">{{header.label}}</th>
    </tr>
    </thead>
    <tbody>
    <tr ng-repeat="user in users" ng-class-odd="'trOdd'" ng-class-even="'trEven'" ng-dblclick="rowDoubleClicked(user)">
        <td ng-repeat="(key,val) in user | orderBy:userOrder(key)">{{val}}</td>
    </tr>
    </tbody>
    <tfoot>

    </tfoot>
</table>

请参考此链接https://gist.github.com/ebellinger/4399082


1

0

首先,我想感谢@MaximShoustin。

由于您的贡献,我现在有了一个非常好的表格。

我对$scope.range$scope.setPage进行了一些小修改。

通过这种方式,我现在可以去到最后一页或回到第一页。而且当我翻到下一页或上一页时,当$scope.gap跨越时导航也会发生变化。当前页不总是在第一页位置。对我来说,这看起来更漂亮。

这里是新的JSFiddle示例: http://jsfiddle.net/qLBRZ/3/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接