获取JSON数组(API),其中对象位于带有Javascript的对象中



我使用下面的代码来构建一个基于API的表,当数组中有对象时(例如lineStatuses[0].statusSeverityDescription)就可以了,但是当数组中、对象中有对象的时候,它就不起作用了,我会返回结果[object object]。

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

[
{
"$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使用API的更新数据来刷新tube-disrupt-DIV,但这不起作用。下面是代码(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;
}

下面的代码将为您生成一个表。通用tableMaker函数采用第一个参数中提供的一个对象数组或多个对象数组。所有对象都应该具有相同的键(属性),因为这些键用于创建表标题(如果第二个参数设置为true),并且这些值用于创建每一行。它将返回一个HTML表格文本。您可以在此处看到tableMaker函数处理较小大小的数据。你也可以用你可能产生的一些样本和简单的数据来练习它。

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

让我们看看

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);

我使用了箭头函数,但它们可能在Safari或IE中不起作用。您可能需要将它们转换为传统的函数表示法。

您也可以在repl.it上试用代码,在那里您可以看到通过console.log显示的HTML文本

最新更新