2016-06-11 32 views
0

我使用下面的代碼來建立一個基於API的表,並且當數組中的對象存在時很好(例如lineStatuses [0] .statusSeverityDescription) ,但是當有一個對象,在一個對象中,在一個數組中,它不起作用,我得到返回結果[object Object]。獲取JSON數組(API),其中對象是在與對象的對象使用Javascript

下面是從URL的JSON數據的樣本(我期待未定義的第一條記錄將被返回):

[ 

    { 

    "$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; 
} 

回答

0

下面的代碼會爲您生成一個表格。通用tableMaker函數接受第一個參數中提供的一個對象數組或一個由多個對象組成的數組。所有對象都應具有相同的鍵(屬性),因爲這些鍵用於創建表頭(如果第二個參數設置爲true)並且這些值用於創建每一行。它將返回一個HTML表格文本。您可以在here處看到使用較小尺寸數據的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文本。