使用Javascript获取JSON数组(API),其中对象在对象中

时间:2016-06-11 19:32:30

标签: javascript arrays json

我正在使用下面的代码构建一个基于API的表,当数组中的对象存在时(例如lineStatuses [0] .statusSeverityDescription)很好,但是当一个对象存在于一个对象中时,一个数组,它不起作用,我得到结果[object Object]返回。

以下是来自URL的JSON数据示例(我希望第一条记录返回Undefined):

[

  {

    "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities",

    "id": "bakerloo",

    "name": "Bakerloo",

    "modeName": "tube",

    "disruptions": [],

    "created": "2016-06-03T12:36:54.19Z",

    "modified": "2016-06-03T12:36:54.19Z",

    "lineStatuses": [

      {

        "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities",

        "id": 0,

        "statusSeverity": 10,

        "statusSeverityDescription": "Good Service",

        "created": "0001-01-01T00:00:00",

        "validityPeriods": []

      }

    ],

    "routeSections": [],

    "serviceTypes": [

      {

        "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities",

        "name": "Regular",

        "uri": "/Line/Route?ids=Bakerloo&serviceTypes=Regular"

      }

    ]

  },

  {

    "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities",

    "id": "central",

    "name": "Central",

    "modeName": "tube",

    "disruptions": [],

    "created": "2016-06-03T12:36:54.037Z",

    "modified": "2016-06-03T12:36:54.037Z",

    "lineStatuses": [

      {

        "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities",

        "id": 0,

        "lineId": "central",

        "statusSeverity": 5,

        "statusSeverityDescription": "Part Closure",

        "reason": "CENTRAL LINE: Saturday 11 and Sunday 12 June, no service between White City and Ealing Broadway / West Ruislip. This is to enable track replacement work at East Acton and Ruislip Gardens.  Replacement buses operate.",

        "created": "0001-01-01T00:00:00",

        "validityPeriods": [

          {

            "$type": "Tfl.Api.Presentation.Entities.ValidityPeriod, Tfl.Api.Presentation.Entities",

            "fromDate": "2016-06-11T03:30:00Z",

            "toDate": "2016-06-13T01:29:00Z",

            "isNow": false

          }

        ],

        "disruption": {

          "$type": "Tfl.Api.Presentation.Entities.Disruption, Tfl.Api.Presentation.Entities",

          "category": "PlannedWork",

          "categoryDescription": "PlannedWork",

          "description": "CENTRAL LINE: Saturday 11 and Sunday 12 June, no service between White City and Ealing Broadway / West Ruislip. This is to enable track replacement work at East Acton and Ruislip Gardens.  Replacement buses operate.",

          "additionalInfo": "Replacement buses operate as follows:Service A: White City - East Acton - North Acton - West Acton - Ealing Common (for District and Piccadilly Lines) - Ealing BroadwayService B: White City - North Acton - Northolt - South Ruislip - Ruislip Gardens - West RuislipService C: White City - North Acton - Park Royal (Piccadilly Line) - Hanger Lane - Perivale - Greenford - Northolt",

          "created": "2016-05-12T11:04:00Z",

          "affectedRoutes": [],

          "affectedStops": [],

          "isBlocking": true,

          "closureText": "partClosure"

        }

      }

    ],

    "routeSections": [],

    "serviceTypes": [

      {

        "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities",

        "name": "Regular",

        "uri": "/Line/Route?ids=Central&serviceTypes=Regular"

      }

    ]

  }

]

我也在尝试使用setInterval来刷新管中断DIV,其中包含来自API的更新数据,这不是工作原理。下面是代码(URL返回上面的一些JSON数据)。我有什么想法吗?

var xmlhttp = new XMLHttpRequest();
var url = "https://api.tfl.gov.uk/line/mode/tube/status";

xmlhttp.onreadystatechange=function() {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        myFunctionDisruption(xmlhttp.responseText);
    }
};

xmlhttp.open("GET", url, true);
xmlhttp.send();

setInterval(myFunctionDisruption, 600000);

function myFunctionDisruption(response) {
    var arr = JSON.parse(response);
    var i;
    var out = "<table>";

    for(i = 0; i < arr.length; i++) {
        out += "<tr><td>" +
        arr[i].lineStatuses[0].disruption.description + <!-- DOES NOT WORK -->
        "</td></tr>";
    }
    out += "</table>";
    document.getElementById("tube-disruption").innerHTML = out;
}

1 个答案:

答案 0 :(得分:0)

以下代码将为您生成一个表格。泛型tableMaker函数接受第一个参数中提供的对象数组或多个对象数组。所有对象都应具有相同的键(属性),因为这些键用于创建表头(如果第二个参数设置为true),并且这些值用于创建每一行。它将返回HTML表格文本。您可以在here看到tableMaker函数使用较小尺寸的数据。您也可以使用您可能生成的一些样本和简单数据来练习它。

在您的情况下,您有多个嵌套对象,我想,这些对象需要转换为主表的相应单元格中的单独表。为此,我有另一个函数tabelizer,它通过使用tableMaker函数递归地处理这个工作。 tabelizer的结果是主表的完整HTML文本。

让我们看看

&#13;
&#13;
var tableMaker = (o,h) => {var keys = o.length && Object.keys(o[0]),
                           rowMaker = (a,t) => a.reduce((p,c,i,a) => p + (i === a.length-1 ? "<" + t + ">" + c + "</" + t + "></tr>"
                                                                                           : "<" + t + ">" + c + "</" + t + ">"),"<tr>"),
                           rows = o.reduce((r,c) => r + rowMaker(keys.reduce((v,k) => v.concat(c[k]),[]),"td"),h ? rowMaker(keys,"th") : []);
                           return rows.length ? "<table>" + rows + "</table>" : "";
                          },
data = [
  {
    "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities",
    "id": "bakerloo",
    "name": "Bakerloo",
    "modeName": "tube",
    "disruptions": [],
    "created": "2016-06-03T12:36:54.19Z",
    "modified": "2016-06-03T12:36:54.19Z",
    "lineStatuses": [
      {
        "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities",
        "id": 0,
        "statusSeverity": 10,
        "statusSeverityDescription": "Good Service",
        "created": "0001-01-01T00:00:00",
        "validityPeriods": []
      }
    ],
    "routeSections": [],
    "serviceTypes": [
      {
        "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities",
        "name": "Regular",
        "uri": "/Line/Route?ids=Bakerloo&serviceTypes=Regular"
      }
    ]
  },
  {
    "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities",
    "id": "central",
    "name": "Central",
    "modeName": "tube",
    "disruptions": [],
    "created": "2016-06-03T12:36:54.037Z",
    "modified": "2016-06-03T12:36:54.037Z",
    "lineStatuses": [
      {
        "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities",
        "id": 0,
        "lineId": "central",
        "statusSeverity": 5,
        "statusSeverityDescription": "Part Closure",
        "reason": "CENTRAL LINE: Saturday 11 and Sunday 12 June, no service between White City and Ealing Broadway / West Ruislip. This is to enable track replacement work at East Acton and Ruislip Gardens.  Replacement buses operate.",
        "created": "0001-01-01T00:00:00",
        "validityPeriods": [
          {
            "$type": "Tfl.Api.Presentation.Entities.ValidityPeriod, Tfl.Api.Presentation.Entities",
            "fromDate": "2016-06-11T03:30:00Z",
            "toDate": "2016-06-13T01:29:00Z",
            "isNow": false
          }
        ],
        "disruption": {
          "$type": "Tfl.Api.Presentation.Entities.Disruption, Tfl.Api.Presentation.Entities",
          "category": "PlannedWork",
          "categoryDescription": "PlannedWork",
          "description": "CENTRAL LINE: Saturday 11 and Sunday 12 June, no service between White City and Ealing Broadway / West Ruislip. This is to enable track replacement work at East Acton and Ruislip Gardens.  Replacement buses operate.",
          "additionalInfo": "Replacement buses operate as follows:Service A: White City - East Acton - North Acton - West Acton - Ealing Common (for District and Piccadilly Lines) - Ealing BroadwayService B: White City - North Acton - Northolt - South Ruislip - Ruislip Gardens - West RuislipService C: White City - North Acton - Park Royal (Piccadilly Line) - Hanger Lane - Perivale - Greenford - Northolt",
          "created": "2016-05-12T11:04:00Z",
          "affectedRoutes": [],
          "affectedStops": [],
          "isBlocking": true,
          "closureText": "partClosure"
        }
      }
    ],
    "routeSections": [],
    "serviceTypes": [
      {
        "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities",
        "name": "Regular",
        "uri": "/Line/Route?ids=Central&serviceTypes=Regular"
      }
    ]
  }
],
tabelizer = (a) => a.length ? tableMaker(a.map(e => Object.keys(e).reduce((p,k) => (p[k] = Array.isArray(e[k]) ? tabelizer(e[k]) : e[k],p),{})),true)
                            : "",
tableHTML = tabelizer(data);
                            
document.write(tableHTML);
&#13;
&#13;
&#13;

我使用了箭头功能,但它们可能无法在Safari或IE上运行。您可能需要将它们转换为传统的函数表示法。

您还可以在repl.it处尝试代码,您可以在其中查看通过console.log显示的HTML文本。