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

AngularJS NG-repeat: How to repeat a data inside an ng-repeat that has to filter unique values

我正在从事一个项目,该项目有 JSON 数据,returns 信息结果。基本上,想法是通过使用按类别过滤的 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 选项卡中显示所有这些数据。

我想要这样的东西:

标记如下所示:

<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>

但是当前代码给我的结果是这样的:

每个类别相当于一个nav-link和一个tab-pane。意思是,如果一个类别有多个产品 - 那么 <table> 应该在 ng-repeat 而不是 tab-pane 本身。

这是实现目标的分类理想标记结果:

<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>

有什么方法可以用当前的数据结构达到我想要的结果吗?谢谢大家!

 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;
                }
        })
li.ACTIVE{
                        background:green;
                 
                }
                li{
                        list-style-type:none;
                }
                li a{
                        cursor:pointer;
                }
                                li.ACTIVE a {
                                        color:white;
                                        font-weight:700;
                                }
<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>

首先,您应该将选项卡定位为 id,并且您可以将每个选项卡设置为与 data.category 具有相同的 id,而不是 $index ; toggle 应该是 data-toggle,否则它将永远无法与 bootstrap 选项卡一起使用:

<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 类别进行比较:

<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。

演示 -> http://plnkr.co/edit/ZtZRA2im8Wxr1TaNWfkt?p=preview