【问题标题】:Output API JSON data in HTML table that has dynamic and static sections在具有动态和静态部分的 HTML 表中输出 API JSON 数据
【发布时间】:2022-01-20 15:32:55
【问题描述】:

我正在使用外部 API、JavaScript 和 HTML 为我的客户构建期货市场数据表。来自 JSON 响应的数据需要输出到与以下屏幕截图匹配的表中。

表中的动态数据需要分两部分加载,中间有一个静态部分。下面是一个代码示例。 HTML 详细说明了它的外观,但 JavaScript 是我目前正在使用的。我附上了第二张截图,显示了我在本地计算机上的当前输出。

如何调整我的 JavaScript 和 HTML 代码以显示动态商品名称和符号,下面是静态列标题,然后是动态数据行。

我正在使用 vanilla JS,不想要任何 jQuery 解决方案。谢谢。

const futures = (() => {
  const futuresTable = document.querySelector("[data-futures]");

  // Bail if data-futures attribute does not exist in DOM
  if (!futuresTable) {
    return;
  }

  const fetchData = () => {
    const apiKey = "";
    const request = `https://api.dtn.com/markets/symbols/%40S%60%23%23%203%2C%40C%60%23%23%203%2C%40W%60%23%23%203/quotes?priceFormat=decimal&type=A&symbolLimit=10&apikey=${apiKey}`;

    fetch(request)
      .then(response => response.json())
      .then((data) => displayData(data))
      .catch(error => {
        console.log(error);
      });
  }
  fetchData();

  const displayData = (data) => {
    // marketsFeed.classList.add("loaded");
    const commodities = data;

    const locale = 'en-CA';
    const dateOptions = {
      month: 'long',
      year: 'numeric',
    };

    for (let commodity of commodities) {
      console.log(commodity);
      let name = commodity.userDescription;
      let month = new Date(commodity.contractDate).toLocaleDateString("en-CA", {
        year: 'numeric',
        month: 'long'
      });
      let description = commodity.symbol.description;
      let symbol = commodity.actualSymbol;
      let last = commodity.last.number;
      let change = commodity.change.number;
      let high = commodity.high.number;
      let low = commodity.low.number;
      let settleDate = new Date(commodity.settleDate).toLocaleDateString("en-CA", {
        year: 'numeric',
        month: 'long',
        day: '2-digit'
      });
      let settlePrice = commodity.settlePrice.number;
      dataTable(name, month, description, symbol, last, change, high, low, settleDate, settlePrice);
    }
  }

  const dataTable = (name, month, description, symbol, last, change, high, low, settleDate, settlePrice) => {
    const dataRow = `
      <thead>
        <tr>
          <th colspan="9">${name}</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th>Month</th>
          <th>Symbol</th>
          <th>Last</th>
          <th>Change</th>
          <th>High</th>
          <th>Low</th>
          <th>Settle Date</th>
          <th>Settle Price</th>
          <th>More</th>
        </tr>
        <tr>
          <td>${month}</td>
          <td>${symbol}</td>
          <td>${last}</td>
          <td>${change}</td>
          <td>${high}</td>
          <td>${low}</td>
          <td>${settleDate}</td>
          <td>${settlePrice}</td>
        </tr>
      </tbody>
    `;
    futuresTable.insertAdjacentHTML("beforeend", dataRow);
  }
})();
table {
  border-collapse: collapse;
  border: 1px solid #ccc;
  font-family: sans-serif;
}

table th,
table td {
  padding: 0.5rem;
  border: 1px solid #ccc;
}

table th {
  text-align: left;
}
<table data-futures>
  <tbody>
    <tr>
      <th colspan="9">
        <!-- Dynamic HTML table content -->
        <!-- commodity is returned from the JSON fetch response -->
        ${commodity.userDescription}<span>${commodity.symbol}</span>
      </th>
    </tr>
    <tr>
      <!-- Static HTML table content -->
      <th scope="col">Month</th>
      <th scope="col">Last</th>
      <th scope="col">Change</th>
      <th scope="col">High</th>
      <th scope="col">Low</th>
      <th scope="col">Settle Date</th>
      <th scope="col">Settle Price</th>
      <th scope="col">More</th>
    </tr>
    <tr>
      <!-- Dynamic HTML table content -->
      <td>August 2022</td>
      <td>1265'2</td>
      <td>-2'4</td>
      <td>1275'2</td>
      <td>1261'4</td>
      <td>October 27, 2021</td>
      <td>1265'2</td>
      <td>Icon</td>
    </tr>
    <tr>
      <!-- Dynamic HTML table content -->
      <td>August 2022</td>
      <td>1265'2</td>
      <td>-2'4</td>
      <td>1275'2</td>
      <td>1261'4</td>
      <td>October 27, 2021</td>
      <td>1265'2</td>
      <td>Icon</td>
    </tr>
  </tbody>
  <tbody>
    <tr>
      <th colspan="9">
        <!-- Dynamic HTML table content -->
        <!-- commodity is returned from the JSON fetch response -->
        ${commodity.userDescription}<span>${commodity.symbol}</span>
      </th>
    </tr>
    <tr>
      <!-- Static HTML table content -->
      <th scope="col">Month</th>
      <th scope="col">Last</th>
      <th scope="col">Change</th>
      <th scope="col">High</th>
      <th scope="col">Low</th>
      <th scope="col">Settle Date</th>
      <th scope="col">Settle Price</th>
      <th scope="col">More</th>
    </tr>
    <tr>
      <!-- Dynamic HTML table content -->
      <td>August 2022</td>
      <td>1265'2</td>
      <td>-2'4</td>
      <td>1275'2</td>
      <td>1261'4</td>
      <td>October 27, 2021</td>
      <td>1265'2</td>
      <td>Icon</td>
    </tr>
    <tr>
      <!-- Dynamic HTML table content -->
      <td>August 2022</td>
      <td>1265'2</td>
      <td>-2'4</td>
      <td>1275'2</td>
      <td>1261'4</td>
      <td>October 27, 2021</td>
      <td>1265'2</td>
      <td>Icon</td>
    </tr>
  </tbody>
</table>

【问题讨论】:

    标签: javascript arrays json for-loop object


    【解决方案1】:

    我认为您的问题参考了调用堆栈。尝试完成从 API 获取数据,然后使用 displayData 显示表格。你可以在 JavaScript 中找到 await 或 Promise。 谢谢

    【讨论】:

    • 对不起,这个答案并没有解决我的问题。获取请求工作正常。问题在于使用我上面详述的结构输出返回的数据。
    【解决方案2】:

    我认为这里的问题是在 dataRow 中显示的是整个数据,这就是列名重复的原因。

    您可以对同名商品进行分组。

    数据分组可以参考https://stackoverflow.com/a/54203304/17090620

    然后在显示表格的同时,

    dataColumn = `
    <thead>
            <tr>
              <th colspan="9">${name}</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <th>Month</th>
              <th>Symbol</th>
              <th>Last</th>
              <th>Change</th>
              <th>High</th>
              <th>Low</th>
              <th>Settle Date</th>
              <th>Settle Price</th>
              <th>More</th>
            </tr>
    `
    dataRow = groupedCommodities[name].map((item) => 
    <tr>
    <td>${item.month}</td>
    <td>${item.symbol}</td>
    ...
    </tr>
    )
    futuresTable.insertAdjacentHTML("beforeend", dataColumn);
    futuresTable.insertAdjacentHTML("beforeend", dataRow);
    futuresTable.insertAdjacentHTML("beforeend", `</tbody>`);
    
    

    这样的事情应该可以工作。

    【讨论】:

    • 小心将数据简单地连接到 HTML 中。它可能导致无效的 HTML 甚至 XSS 漏洞。数据必须正确转义。最好为此使用适当的模板引擎。
    猜你喜欢
    • 2016-10-27
    • 2013-04-29
    • 1970-01-01
    • 1970-01-01
    • 2014-11-27
    • 2013-07-10
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多