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。
我正在从事一个项目,该项目有 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。