Группировать строки в данных HTML на основе значения данных JSON.И разверните строку при нажатии на каждое значение, показывая детали - PullRequest
0 голосов
/ 24 мая 2018

У меня есть данные JSON следующим образом:

{
"data": [{
    "appDetails": [{
        "appDescription": [{
                "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"
            }
        ]
    }]
}]}

Мой угловой код js - это метод http.get для извлечения вышеуказанного json из облачной базы данных и использования $scope для передачи данных в htmlТаблица.Угловой код js:

  function DashboardTablesPageCtrl($scope,$http,$timeout) {


$scope.tableData = [];
$scope.myFilter = ""

  var req = {
    method: 'POST',
    url: 'https://'+ACCOUNTNAME+'.cloudant.com/_session',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    data: 'name='+APIKEY+'&password='+APIPASSWORD,
    withCredentials: true
  }


 $http(req).then(function(result){
        //Grab data
        req = {
          method: 'GET',
          url: 'https://'+ACCOUNTNAME+'.cloudant.com/'+DATABASE+'/_all_docs',
          withCredentials: true
        }
        var i = 0;

        $timeout(function(){
        $http(req).then(function(result){
            for(i=0;i<result.data.total_rows;i++){
                var id = result.data.rows[i].id

                $http.get('https://'+ACCOUNTNAME+'.cloudant.com/'+DATABASE+'/'+id).then(function(data){
                    var data = data.data

                        angular.forEach(data.data[0].appDetails, function(appDetail, index) {
                        angular.forEach(appDetail.appDescription, function(appDescription, index){
                            $scope.tableData.push(appDescription);

                        });
                    });

                })

    }       
  },
  function(){
    console.log("Failed at grabbing data");
  });
}, 
function(){
  console.log('Failed at authenticating');
});

});}})();

Я использовал ng-repeat в моем html табличном теле для отображения данных, как показано ниже:

<tbody>
<tr ng-repeat="item in tableData | filter: myFilter ">
  <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>

Это отображает все данные в разных строках.Мне нужно, чтобы все данные App X, App Y и App Z были сгруппированы, и только три показанные строки и щелчок App X должны отобразить данные App X, развернув строки в одной таблице.

Я не могу этого добиться, так как получаю только разные строки для каждой информации в таблице.Пожалуйста, помогите мне достичь этого.

1 Ответ

0 голосов
/ 24 мая 2018

Идея состоит в том, чтобы показать и скрыть строки для данного имени приложения, когда пользователь нажимает на строку с именем приложения.Это может быть достигнуто за счет того, что строки с именами только приложений (для щелчка по ним) и строки, отфильтрованные по именам приложений:

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