AngularJS NG-repeat:如何重复必须过滤唯一值的ng-repeat内的数据

时间:2017-12-22 03:24:27

标签: javascript angularjs json angularjs-ng-repeat

我正在开发一个具有返回信息结果的JSON数据的项目。基本上,我们的想法是使用BootStrap选项卡显示这些数据,其中按类别进行过滤。

模拟JSON数据:

"result": [
    {
        category: "A",
        price: "499.00",
        productName: "AAA",
        productConfig: {
            specs: "Lorem ipsum",
            creditAllowed: false,
            description: "blah blah",
            ...
        }
    },
    {
        category: "A",
        price: "479.00",
        productName: "AAB",
        productConfig: {
            specs: "Lorem ipsum",
            creditAllowed: true,
            description: "blah blah",
            ...
        }
    },
    {
        category: "B",
        price: "1299.00",
        productName: "BBB",
        productConfig: {
            specs: "Lorem ipsum",
            creditAllowed: true,
            description: "blah blah",
            ...
        }
    },
    {
        category: "A",
        price: "359.00",
        productName: "AXX",
        productConfig: {
            specs: "Lorem ipsum",
            creditAllowed: true,
            description: "blah blah",
            ...
        }
    },
]

鉴于此数据。我需要当然,使用ng-repeat在我的bootStrap标签中显示所有这些数据。

我想要这样的事情:

enter image description here

标记看起来像这样:

<a load-data data-param="1">Load me</a>

该指令正在调用服务,所有数据都在作用域内。现在元素有这个:

<ul class="nav nav-tabs col-lg-4 col-md-4" role="tablist">
    <li ng-repeat="data in tableData | unique: 'category'"><a href="#{{$index}}" role="tab" toggle="tab"></li>
</ul>


...

<div class="tab-content col-lg-8 col-md-8">
    <div role="tabpanel" class="tab-pane fade" id="{{$index}}" ng-repeat="contents in tableData | unique: 'category'">
         <h1>{{ contents.category }}</h1>
         <div class="tab-content-details">
             <table class="table">
                 <tr>
                     <td>{{ contents.price }}</td>
                     <td>{{ contents.productConfig.specs }}</td>
                     <td>{{ contents.productConfig.description }}</td>
                 </tr>
             </table>
         </div>
    </div>
</div>

但是当前代码给我的结果如下:

enter image description here

每个类别相当于一个nav-link和一个tab-pane。这意味着,如果某个类别包含多个产品,则<table>应该位于ng-repeat而不是tab-pane本身。

以下是实现目标的 sort-of 理想标记结果:

<ul class="nav nav-tabs col-lg-4 col-md-4" role="tablist">
    <li class="active"><a href="#0" role="tab" toggle="tab">Category A</li>
    <li><a href="#1" role="tab" toggle="tab">Category B</li>
    ...
</ul>


...

<div class="tab-content col-lg-8 col-md-8">
    <div role="tabpanel" class="tab-pane fade active" id="0">
         <h1>Category A</h1>
         <div class="tab-content-details">
             <table class="table">
                 <tr>
                     <td>499.00</td>
                     <td>Lorem ipsum</td>
                     <td>blah blah</td>
                 </tr>
                 <tr>
                     <td>479.00</td>
                     <td>Lorem ipsum</td>
                     <td>blah blah</td>
                 </tr>
             </table>
         </div>
    </div>
    <div role="tabpanel" class="tab-pane fade" id="1">
         <h1>Category B</h1>
         <div class="tab-content-details">
             <table class="table">
                 <tr>
                     <td>1299.00</td>
                     <td>Lorem ipsum</td>
                     <td>blah blah</td>
                 </tr>
             </table>
         </div>
    </div>
</div>

有没有办法可以用当前的数据结构实现我想要的结果?谢谢大家!

2 个答案:

答案 0 :(得分:1)

首先,您应将标签定位为id,然后您可以将每个标签设置为与id相同的data.category,而不是$index; toggle应该是data-toggle,否则它永远不会与引导标签一起使用:

<ul class="nav nav-tabs col-lg-4 col-md-4" role="tablist">
  <li ng-repeat="data in tableData | unique: 'category'">
     <a href="#{{data.category}}" role="tab" data-toggle="tab">
       Category {{ data.category }}         
     </a>  
  </li>
</ul>

然后,您可以使用嵌套的ng-repeat覆盖与上述相同的唯一重复,并使用ng-if将整体data类别与嵌套的content类别进行比较:< / p>

<div class="tab-content col-lg-8 col-md-8">
  <div role="tabpanel" ng-repeat="data in tableData | unique: 'category'" class="tab-pane" id="{{data.category}}">
    <div ng-repeat="content in tableData">
      <div ng-if="content.category === data.category">
        {{ content | json }}
        <hr>
      </div>     
    </div>
  </div>  
</div>

现在您可以根据需要设置每个项目的样式,我只是渲染出JSON。

演示 - &gt;的 http://plnkr.co/edit/ZtZRA2im8Wxr1TaNWfkt?p=preview

答案 1 :(得分:0)

&#13;
&#13;
 var app = angular.module("App", []);
                app.controller('AppCtrl',function($scope){
                        $scope.json_data ={ 
                        "result": [
    {
        category: "A",
        price: "499.00",
        productName: "AAA",
        productConfig: {
            specs: "Lorem ipsum",
            creditAllowed: false,
            description: "blah blah",
        }
    },
    {
        category: "A",
        price: "479.00",
        productName: "AAB",
        productConfig: {
            specs: "Lorem ipsum",
            creditAllowed: true,
            description: "blah blah",
        }
    },
    {
        category: "B",
        price: "1299.00",
        productName: "BBB",
        productConfig: {
            specs: "Lorem ipsum",
            creditAllowed: true,
            description: "blah blah",
        }
    },
    {
        category: "A",
        price: "359.00",
        productName: "AXX",
        productConfig: {
            specs: "Lorem ipsum",
            creditAllowed: true,
            description: "blah blah",
        }
    },
]
}               
                $scope.tableData_obj    = {}
                $scope.filterTxn        = {}
                $scope.json_data['result'].forEach(function(val){
                                if(val['category'] in  $scope.tableData_obj)
                                        return;
                                else
                                        $scope.tableData_obj[val['category']] = true;
                })
                $scope.tableData        = Object.keys($scope.tableData_obj)     
                $scope.own_filter       = function(values){
                        if(! $scope.filterTxn['values'])
                                return true;
                        if(values['category'] == $scope.filterTxn['values'])
                                return true
                        else
                                return false;   
                }
                $scope.update_filterTxn_values = function(data){
                        $scope.filterTxn['values'] = data;
                }
        })
&#13;
li.ACTIVE{
                        background:green;
                 
                }
                li{
                        list-style-type:none;
                }
                li a{
                        cursor:pointer;
                }
                                li.ACTIVE a {
                                        color:white;
                                        font-weight:700;
                                }
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="App" ng-controller="AppCtrl ">
                <ul class="nav nav-tabs col-lg-4 col-md-4" role="tablist">
                        <li ng-repeat="data in tableData track by $index" ng-class="{'ACTIVE':filterTxn['values'] == data}"><a   ng-click="update_filterTxn_values(data)" role="tab" toggle="tab">{{'click_here to filter_data - '+data}}</a></li>

                </ul>
                <h1>{{'Selected Category - '+filterTxn['values']}}</h1>
                <div class="tab-content col-lg-8 col-md-8">
                    <div role="tabpanel" class="tab-pane fade" id="{{$index}}" ng-repeat="contents in json_data['result'] |filter:own_filter track by $index">
                         <h1>{{ contents.category }}</h1>
                         <div class="tab-content-details">
                             <table class="table">
                                 <tr>
                                     <td>{{ contents.price }}</td>
                                     <td>{{ contents.productConfig.specs }}</td>
                                     <td>{{ contents.productConfig.description }}</td>
                                 </tr>
                             </table>
                         </div>
                    </div>
                </div>

        </div>
&#13;
&#13;
&#13;