Идея состоит в том, чтобы показать и скрыть строки для данного имени приложения, когда пользователь нажимает на строку с именем приложения.Это может быть достигнуто за счет того, что строки с именами только приложений (для щелчка по ним) и строки, отфильтрованные по именам приложений:
<tr><td colspan="10" ng-click=swapExpandingX()>App X</td></tr>
<tr ng-show="expandX" ng-repeat="item in tableData | filter: { appName: 'App X'}">
<td>{{item.appName}}</td>
<td>{{item.GitTag}}</td>
...
<td>{{item.CodeCoverage}}</td>
</tr>
<tr><td colspan="10" ng-click=swapExpandingY()>App Y</td></tr>
<tr ng-show="expandY" ng-repeat="item in tableData | filter: { appName: 'App Y'}">
<td>{{item.appName}}</td>
<td>{{item.GitTag}}</td>
...
<td>{{item.CodeCoverage}}</td>
</tr>
И функции подстановки в контроллере, вызываемые по щелчку:
$scope.expandX = false;
$scope.swapExpandingX = function() {
$scope.expandX = !$scope.expandX;
}
Посмотрите, как это работает, во фрагменте ниже.
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.expandX = false;
$scope.expandY = false;
$scope.swapExpandingX = function() {
$scope.expandX = !$scope.expandX;
}
$scope.swapExpandingY = function() {
$scope.expandY = !$scope.expandY;
}
$scope.tableData = [{
"appName": "App X",
"timeStamp": "",
"GitTag": "RELEASE-1.0.1.25",
"blocker": "3",
"critical": "4",
"major": "30",
"minor": "2",
"UnitTestsTotal": "59",
"FailedTests": "0",
"CodeCoverage": "90"
},
{
"appName": "App X",
"timeStamp": "",
"GitTag": "RELEASE-1.0.1.24",
"blocker": "3",
"critical": "4",
"major": "30",
"minor": "2",
"UnitTestsTotal": "59",
"FailedTests": "0",
"CodeCoverage": "90"
},
{
"appName": "App X",
"timeStamp": "",
"GitTag": "RELEASE-1.0.1.23",
"blocker": "3",
"critical": "4",
"major": "30",
"minor": "2",
"UnitTestsTotal": "59",
"FailedTests": "0",
"CodeCoverage": "90"
},
{
"appName": "App Y",
"timeStamp": "",
"GitTag": "RELEASE-1.0.1.1",
"blocker": "3",
"critical": "4",
"major": "30",
"minor": "2",
"UnitTestsTotal": "59",
"FailedTests": "0",
"CodeCoverage": "90"
},
{
"appName": "App Y",
"timeStamp": "",
"GitTag": "RELEASE-1.0.1.2",
"blocker": "3",
"critical": "4",
"major": "30",
"minor": "2",
"UnitTestsTotal": "59",
"FailedTests": "0",
"CodeCoverage": "90"
},
{
"appName": "App Z",
"timeStamp": "",
"GitTag": "RELEASE-1.0.0.0",
"blocker": "3",
"critical": "4",
"major": "30",
"minor": "2",
"UnitTestsTotal": "59",
"FailedTests": "0",
"CodeCoverage": "90"
},
{
"appName": "App Z",
"timeStamp": "",
"GitTag": "RELEASE-1.0.0.1",
"blocker": "3",
"critical": "4",
"major": "30",
"minor": "2",
"UnitTestsTotal": "59",
"FailedTests": "0",
"CodeCoverage": "90"
}
]
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<table>
<tbody>
<tr><td colspan="10" ng-click=swapExpandingX()>App X</td></tr>
<tr ng-show="expandX" ng-repeat="item in tableData | filter: { appName: 'App X'}">
<td>{{item.appName}}</td>
<td>{{item.GitTag}}</td>
<td>{{item.blocker}}</td>
<td>{{item.critical}}</td>
<td>{{item.major}}</td>
<td>{{item.minor}}</td>
<td>{{item.UnitTestsTotal}}</td>
<td>{{item.FailedTests}}</td>
<td>{{item.CodeCoverage}}</td>
</tr>
<tr><td colspan="10" ng-click=swapExpandingY()>App Y</td></tr>
<tr ng-show="expandY" ng-repeat="item in tableData | filter: { appName: 'App Y'}">
<td>{{item.appName}}</td>
<td>{{item.GitTag}}</td>
<td>{{item.blocker}}</td>
<td>{{item.critical}}</td>
<td>{{item.major}}</td>
<td>{{item.minor}}</td>
<td>{{item.UnitTestsTotal}}</td>
<td>{{item.FailedTests}}</td>
<td>{{item.CodeCoverage}}</td>
</tr>
</tbody>
</table>
</div>
Удаление повторений кода
Хорошо, все работает.Теперь мы можем улучшить этот код, удалив повторения кода в html и controller.
Давайте сохраним appNames в массиве appNames
.Вы можете жестко закодировать его
$scope.appNames = ["App X", "App Y", "App Z"];
или извлекать его динамически из tableData
$scope.appNames = Array.from(new Set($scope.tableData.map(a => a.appName)));
Нам понадобится структура для хранения информации, если строка для данного имени приложения должна быть расширена.Давайте создадим карту expanding
и установим значение false
для каждого имени приложения в качестве ключа.
$scope.expanding = {};
for (index = 0; index < $scope.appNames.length; index++) {
$scope.expanding[$scope.appNames[index]] = false;
}
Теперь мы можем иметь HTML без повторений:
<table>
<tbody ng-repeat="name in appNames">
<tr>
<td colspan="10" ng-click=swapExpanding(name)>{{name}}</td>
</tr>
<tr ng-show="expanding[name]" ng-repeat="item in tableData | filter: { appName: name}">
<td>{{item.appName}}</td>
<td>{{item.GitTag}}</td>
...
<td>{{item.CodeCoverage}}</td>
</tr>
</tbody>
</table>
и простую функцию обмена:
$scope.swapExpanding = function(name) {
$scope.expanding[name] = !$scope.expanding[name];
}
Посмотрите, как это работает, во фрагменте ниже.
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.tableData = [{
"appName": "App X",
"timeStamp": "",
"GitTag": "RELEASE-1.0.1.25",
"blocker": "3",
"critical": "4",
"major": "30",
"minor": "2",
"UnitTestsTotal": "59",
"FailedTests": "0",
"CodeCoverage": "90"
},
{
"appName": "App X",
"timeStamp": "",
"GitTag": "RELEASE-1.0.1.24",
"blocker": "3",
"critical": "4",
"major": "30",
"minor": "2",
"UnitTestsTotal": "59",
"FailedTests": "0",
"CodeCoverage": "90"
},
{
"appName": "App X",
"timeStamp": "",
"GitTag": "RELEASE-1.0.1.23",
"blocker": "3",
"critical": "4",
"major": "30",
"minor": "2",
"UnitTestsTotal": "59",
"FailedTests": "0",
"CodeCoverage": "90"
},
{
"appName": "App Y",
"timeStamp": "",
"GitTag": "RELEASE-1.0.1.1",
"blocker": "3",
"critical": "4",
"major": "30",
"minor": "2",
"UnitTestsTotal": "59",
"FailedTests": "0",
"CodeCoverage": "90"
},
{
"appName": "App Y",
"timeStamp": "",
"GitTag": "RELEASE-1.0.1.2",
"blocker": "3",
"critical": "4",
"major": "30",
"minor": "2",
"UnitTestsTotal": "59",
"FailedTests": "0",
"CodeCoverage": "90"
},
{
"appName": "App Z",
"timeStamp": "",
"GitTag": "RELEASE-1.0.0.0",
"blocker": "3",
"critical": "4",
"major": "30",
"minor": "2",
"UnitTestsTotal": "59",
"FailedTests": "0",
"CodeCoverage": "90"
},
{
"appName": "App Z",
"timeStamp": "",
"GitTag": "RELEASE-1.0.0.1",
"blocker": "3",
"critical": "4",
"major": "30",
"minor": "2",
"UnitTestsTotal": "59",
"FailedTests": "0",
"CodeCoverage": "90"
}
]
$scope.appNames = Array.from(new Set($scope.tableData.map(a => a.appName)));;
$scope.expanding = {};
for (index = 0; index < $scope.appNames.length; index++) {
$scope.expanding[$scope.appNames[index]] = false;
}
$scope.swapExpanding = function(name) {
$scope.expanding[name] = !$scope.expanding[name];
}
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td,
th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<table>
<tbody ng-repeat="name in appNames">
<tr>
<td colspan="10" ng-click=swapExpanding(name)>{{name}}</td>
</tr>
<tr ng-show="expanding[name]" ng-repeat="item in tableData | filter: { appName: name}">
<td>{{item.appName}}</td>
<td>{{item.GitTag}}</td>
<td>{{item.blocker}}</td>
<td>{{item.critical}}</td>
<td>{{item.major}}</td>
<td>{{item.minor}}</td>
<td>{{item.UnitTestsTotal}}</td>
<td>{{item.FailedTests}}</td>
<td>{{item.CodeCoverage}}</td>
</tr>
</tbody>
</table>
</div>