【问题标题】:HTML Table dynamically generate columns using ng-repeatHTML Table 使用 ng-repeat 动态生成列
【发布时间】:2017-04-13 12:58:21
【问题描述】:

您能帮我使用带有 Angular ng-repeat 的 JSON 数据生成 HTML 表吗?

Demo

JSON 数据

{
  "account": {
    "accountId": "54545",
    "premise": {
      "address": {
        "address1": "1800 Bishop Gate Boulevard",
        "address2": "Apartment 129",
        "city": "Mount Laurel",
        "province": "NJ",
        "postalCode": "08054",
        "country": "US",
        "direction": null,
        "externalReference": null,
        "verified": false
      },
      "timeZone": "US_EASTERN",
      "locale": "EN",
      "camera": [
        {
          "id": "175277.2",
          "name": "camera1",
          "macAddress": "00:0E:8F:5B:AB:88",
          "manufacturer": "gabreal",
          "model": "iCamera",
          "serialNumber": "000E8F5BAB88",
          "firmwareVersion": "3.0.01.07",
          "hardwareVersion": null
        },
        {
          "id": "175277.3",
          "name": "camera2",
          "macAddress": "D4:21:22:D9:D0:73",
          "manufacturer": "gabreal",
          "model": "iCamera2-C",
          "serialNumber": "D42122D9D073",
          "firmwareVersion": "3.0.02.39",
          "hardwareVersion": null
        },
        {
          "id": "175277.1",
          "name": "camera3",
          "macAddress": "00:0E:8F:95:A8:A6",
          "manufacturer": "gabreal",
          "model": "SerComm_Camera_8021",
          "serialNumber": "000E8F95A8A6",
          "firmwareVersion": "1.0.24",
          "hardwareVersion": null
        }
      ],
      "thermostat": [
        {
          "id": "0024460000084172.10",
          "name": "Thermostat1",
          "type": "THERMOSTAT",
          "manufacturer": "RTCOA",
          "serialNumber": null,
          "firmwareVersion": "0x00000587",
          "hardwareVersion": "192",
          "model": "CT30S"
        },
        {
          "id": "000d6f0003ec6669.1",
          "name": "Thermostat2",
          "type": "THERMOSTAT",
          "manufacturer": "CentraLite Systems",
          "serialNumber": null,
          "firmwareVersion": "0x1418468c",
          "hardwareVersion": "2",
          "model": "3156105"
        }
      ],
      "zone": [
        {
          "id": 1,
          "name": "one",
          "type": "DOOR",
          "functionType": "ENTRY_EXIT",
          "sensor": [
            {
              "id": 1,
              "type": "DRY_CONTACT",
              "sourceType": "ZIGBEE",
              "serialNumber": "000d6f00030cdbcf.1",
              "model": "MCT-320 SMA",
              "manufacturer": "Visonic",
              "firmwareVersion": "0x00040008",
              "hardwareVersion": "1"
            }
          ]
        },
        {
          "id": 2,
          "name": "Motion",
          "type": "MOTION",
          "functionType": "INTERIOR_FOLLOWER",
          "sensor": [
            {
              "id": 2,
              "type": "MOTION",
              "sourceType": "ZIGBEE",
              "serialNumber": "000d6f0004b2af93.1",
              "model": "NEXT K85 SMA",
              "manufacturer": "Visonic",
              "firmwareVersion": "0x0004000b",
              "hardwareVersion": "1"
            }
          ]
        }
      ],
      "cpe": {
        "cpeId": "9c972684b2ca",
        "name": null,
        "deploymentModel": "WIFI_CLIENT_PSK_2_MODE",
        "serialNumber": null,
        "manufacturer": "Technicolor",
        "model": "TCA203",
        "hardwareRev": "5",
        "passPhrase": "528233",
        "cellularProfileName": null,
        "imeiNumber": 359942045924230,
        "iccId": "89011703258034552401",
        "simCardPhoneNumber": null,
        "simCardAccountNumber": null,
        "wifiMacAddress": "70:25:59:79:E2:EE",
        "firmwareVersion": "7_3_8_050000_201611152386",
        "widget": [
          {
            "name": "com.wsi.android.Gabreal",
            "version": "1.2"
          },
          {
            "name": "com.icontrol.apps.clock",
            "version": "1.0.0.0.3"
          }
        ],
        "module": []
      },
      "premiseId": null
    },
    "source": "INTERNAL"
  }
}

我要生成的表格如下

<table>
  <tr>
    <th>Property<br></th>
    <th>camera</th>
    <th>camera</th>
    <th>camera</th>
    <th>thermostat</th>
    <th>thermostat</th>
    <th>sensor</th>
    <th>sensor</th>
  </tr>
  <tr>
    <td>id</td>
    <td>175277.2</td>
    <td>175277.3</td>
    <td>175277.1</td>
    <td>0024460000084172.10</td>
    <td>000d6f0003ec6669.1</td>
    <td>1</td>
    <td>2</td>
  </tr>
  <tr>
    <td>name</td>
    <td>camera1</td>
    <td>camera2</td>
    <td>camera3</td>
    <td>Thermostat1</td>
    <td>Thermostat2</td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td>macAddress</td>
    <td>00:0E:8F:5B:AB:88</td>
    <td>D4:21:22:D9:D0:73</td>
    <td>00:0E:8F:95:A8:A6</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td>manufacturer</td>
    <td>gabreal</td>
    <td>gabreal</td>
    <td>gabreal</td>
    <td>RTCOA</td>
    <td>CentraLite Systems</td>
    <td>Visonic</td>
    <td>Visonic</td>
  </tr>
</table>

注意:Aruna 已经回答了这个问题,但是当区域对象等不同类型的 JSON 对象与其他对象不同时,它会失败。

【问题讨论】:

  • plnkr.co/edit/zN1KJKqZrBjMsqySkYtC?p=preview .....不确定这是否是最有效的方法,但这绝对可以让您领先一步
  • Anirudh 我不想这样写,因为我只是写了简单的 JSON 来了解逻辑。实际上我的 json 有很多对象,比如相机和恒温器。我想遍历所有对象并获取详细信息。
  • @Batman 你能检查一下下面的解决方案吗?它与对象是通用的。只有 name 和 id 属性是硬编码的
  • @cale_b 请检查我已经明确提到我尝试过的演示的问题Demo
  • 将相关代码复制到您的问题中。

标签: javascript html angularjs angularjs-ng-repeat html-table


【解决方案1】:

这是一个带有对象和属性的generic 解决方案。

根据赏金请求中的 json 更改进行了更新。

var app = angular.module('studentApp', []);

app.controller('StudentCntrl', function($scope,$http) {
    //$http.get('data.json').then(function (response){
	              //console.log(response.data.pages);
                //$scope.deviceInfo = response.data.account.premise;
        //});
  
var responseData = {
  "account": {
    "accountId": "54545",
    "premise": {
      "address": {
        "address1": "1800 Bishop Gate Boulevard",
        "address2": "Apartment 129",
        "city": "Mount Laurel",
        "province": "NJ",
        "postalCode": "08054",
        "country": "US",
        "direction": null,
        "externalReference": null,
        "verified": false
      },
      "timeZone": "US_EASTERN",
      "locale": "EN",
      "camera": [
        {
          "id": "175277.2",
          "name": "camera1",
          "macAddress": "00:0E:8F:5B:AB:88",
          "manufacturer": "gabreal",
          "model": "iCamera",
          "serialNumber": "000E8F5BAB88",
          "firmwareVersion": "3.0.01.07",
          "hardwareVersion": null
        },
        {
          "id": "175277.3",
          "name": "camera2",
          "macAddress": "D4:21:22:D9:D0:73",
          "manufacturer": "gabreal",
          "model": "iCamera2-C",
          "serialNumber": "D42122D9D073",
          "firmwareVersion": "3.0.02.39",
          "hardwareVersion": null
        },
        {
          "id": "175277.1",
          "name": "camera3",
          "macAddress": "00:0E:8F:95:A8:A6",
          "manufacturer": "gabreal",
          "model": "SerComm_Camera_8021",
          "serialNumber": "000E8F95A8A6",
          "firmwareVersion": "1.0.24",
          "hardwareVersion": null
        }
      ],
      "thermostat": [
        {
          "id": "0024460000084172.10",
          "name": "Thermostat1",
          "type": "THERMOSTAT",
          "manufacturer": "RTCOA",
          "serialNumber": null,
          "firmwareVersion": "0x00000587",
          "hardwareVersion": "192",
          "model": "CT30S"
        },
        {
          "id": "000d6f0003ec6669.1",
          "name": "Thermostat2",
          "type": "THERMOSTAT",
          "manufacturer": "CentraLite Systems",
          "serialNumber": null,
          "firmwareVersion": "0x1418468c",
          "hardwareVersion": "2",
          "model": "3156105"
        }
      ],
      "zone": [
        {
          "id": 1,
          "name": "one",
          "type": "DOOR",
          "functionType": "ENTRY_EXIT",
          "sensor": [
            {
              "id": 1,
              "type": "DRY_CONTACT",
              "sourceType": "ZIGBEE",
              "serialNumber": "000d6f00030cdbcf.1",
              "model": "MCT-320 SMA",
              "manufacturer": "Visonic",
              "firmwareVersion": "0x00040008",
              "hardwareVersion": "1"
            }
          ]
        },
        {
          "id": 2,
          "name": "Motion",
          "type": "MOTION",
          "functionType": "INTERIOR_FOLLOWER",
          "sensor": [
            {
              "id": 2,
              "type": "MOTION",
              "sourceType": "ZIGBEE",
              "serialNumber": "000d6f0004b2af93.1",
              "model": "NEXT K85 SMA",
              "manufacturer": "Visonic",
              "firmwareVersion": "0x0004000b",
              "hardwareVersion": "1"
            }
          ]
        }
      ],
      "cpe": {
        "cpeId": "9c972684b2ca",
        "name": null,
        "deploymentModel": "WIFI_CLIENT_PSK_2_MODE",
        "serialNumber": null,
        "manufacturer": "Technicolor",
        "model": "TCA203",
        "hardwareRev": "5",
        "passPhrase": "528233",
        "cellularProfileName": null,
        "imeiNumber": 359942045924230,
        "iccId": "89011703258034552401",
        "simCardPhoneNumber": null,
        "simCardAccountNumber": null,
        "wifiMacAddress": "70:25:59:79:E2:EE",
        "firmwareVersion": "7_3_8_050000_201611152386",
        "widget": [
          {
            "name": "com.wsi.android.Gabreal",
            "version": "1.2"
          },
          {
            "name": "com.icontrol.apps.clock",
            "version": "1.0.0.0.3"
          }
        ],
        "module": []
      },
      "premiseId": null
    },
    "source": "INTERNAL"
  }
};
  
var headerProperty = $scope.headerProperty = 'deviceType';
  
rebuildDeviceInfo(responseData);
  
function rebuildDeviceInfo(data) {
  var deviceInfoData = responseData.account.premise;
  var deviceInfo = [], deviceProperties = [];
  
  // Parse devices
  angular.forEach(deviceInfoData, function(devices, deviceKey) {
    if(angular.isArray(devices)) {
       deviceInfo = deviceInfo.concat(parseDevices(devices, deviceKey));
    }
  });
  
  // Parse device properties
  for(var i = 0; i < deviceInfo.length; i++) {
    var device = deviceInfo[i];
    angular.forEach(device, function(value, deviceProperty) {
      if(deviceProperties.indexOf(deviceProperty) === -1) {
        deviceProperties.push(deviceProperty);
      }
    });
  }
  
  $scope.deviceInfo = deviceInfo;
  $scope.deviceProperties = deviceProperties;
}
  
function parseDevices(dataArray, dataKey) {
     var deviceInfo = [];
     if(angular.isArray(dataArray)) {
       for(var i = 0; i < dataArray.length; i++) {
         var data = dataArray[i];
         if(data.hasOwnProperty('manufacturer') || data.hasOwnProperty('model')) {
           data[headerProperty] = dataKey;
           deviceInfo.push(data);
         } else {
            angular.forEach(data, function(devices, deviceKey) {
              if(angular.isArray(devices)) {
                 deviceInfo = deviceInfo.concat(parseDevices(devices, deviceKey));
              }
            });
         }
       }
     }
    
     return deviceInfo;
}
  
});
<!DOCTYPE html>
<html ng-app="studentApp">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
  <script  src="https://code.angularjs.org/1.4.7/angular.js"></script>
</head>

<body ng-controller="StudentCntrl">

 
    <div class="table-responsive">
        <table class="table table-striped">
          <thead>
            <tr>
              <th>Property</th>
              <th ng-repeat="device in deviceInfo track by $index">{{device[headerProperty]}}</th>
            </tr>
          </thead>
          <tbody>
             <tr ng-repeat="prop in deviceProperties track by $index" ng-if="prop != headerProperty">
                <td>{{prop}}</td>
                <td ng-repeat="device in deviceInfo track by $index">{{device[prop]}}</td>
             </tr>
          </tbody>
        </table>
      </div>
</body>
</html>

【讨论】:

  • 谢谢阿鲁娜!!有没有办法我们可以使用 setRows() 和 setHeaders() 来实现这一点.. Upvoted :)
  • @Batman,对不起,你能解释一下using setRows() and setHeaders() 的含义吗,因为代码已经有了这个。在您的$http 代码中,您只需调用 setData(response.data)` 即可。请解释一下
  • @cale_b 我​​以为他在 Demo url 的 html 中尝试了很少的 ng-repeat https://plnkr.co/edit/tT2ltDz2TquKHjIE8OKD?p=preview
  • @cale_b 我​​不是要求在这里写代码。我要求帮助解决方法
  • @Batman 通常,标题和列数是静态的,行数是动态的。但是对于这种情况,标题和列数是动态的,而行数是静态的。这就是为什么我们必须重建对象。我能做的是,我可以尝试减少两种方法,而不是两种方法。
猜你喜欢
  • 1970-01-01
  • 2018-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
  • 1970-01-01
  • 2014-08-31
相关资源
最近更新 更多