You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取点击航班预订按钮对应的航班数据及解决数组未更新问题

问题分析与解决方案

你的核心问题有两个:

  1. 异步时机错配:then链里的console.log(data.flights[data.bookedFlights[0]])是页面渲染完成后立刻执行的,这时用户还没点击预订按钮,bookedFlights数组自然是空的。点击事件是用户触发的异步操作,必须在点击发生后才能获取到数据。
  2. 数据关联效率低:你现在存的是按钮ID,虽然能通过索引拿到航班,但直接绑定对应航班对象会更直观可靠。

修复后的代码

const fl = fetch("https://mocki.io/v1/fa695c4b-475e-4dfc-8608-952c0c5a28b5");

fl.then((response) => {
  return response.json();
}).then((result) => {
  const fakeFlights = result.flights;
  const table = document.createElement("table");
  const thead1 = document.createElement("thead");
  const thead2 = document.createElement("thead");
  const tbody = document.createElement("tbody");
  // 把购物车数组放在这里,确保点击事件能访问到,也方便后续随时调用
  const bookedFlights = [];

  // 构建主表头
  let row1 = document.createElement("tr");
  let headingTH = document.createElement("th");
  headingTH.innerText = "Available Flights";
  headingTH.colSpan = 7;
  row1.appendChild(headingTH);
  thead1.appendChild(row1);

  // 构建字段表头
  let row2 = document.createElement("tr");
  for (let key in fakeFlights[0]) {
    let heading = document.createElement("th");
    // 格式化表头文本
    switch(key) {
      case "flightNumber":
        heading.innerText = "Flight Number";
        break;
      case "departureTime":
        heading.innerText = "Departure Time";
        break;
      case "arrivalTime":
        heading.innerText = "Arrival Time";
        break;
      default:
        heading.innerText = key;
    }
    row2.appendChild(heading);
  }
  let bookingHeading = document.createElement("th");
  bookingHeading.innerText = "Book the flight";
  row2.appendChild(bookingHeading);
  thead2.appendChild(row2);

  // 构建航班数据行
  for (let i = 0; i < fakeFlights.length; i++) {
    const flight = fakeFlights[i];
    let row = document.createElement("tr");
    for (let key in flight) {
      let rowData = document.createElement("td");
      rowData.innerHTML = flight[key];
      row.appendChild(rowData);
    }
    let btn = document.createElement("button");
    btn.innerText = "Book";
    // 点击事件直接绑定当前航班对象
    btn.addEventListener("click", function() {
      // 可选:避免重复添加同一航班
      if (!bookedFlights.some(item => item.flightNumber === flight.flightNumber)) {
        bookedFlights.push(flight);
        // 实时处理购物车逻辑,比如打印或更新页面展示
        console.log("已添加航班:", flight);
        console.log("当前购物车:", bookedFlights);
        // 更新购物车UI
        updateCartDisplay(bookedFlights);
      } else {
        console.log("该航班已在购物车中");
      }
    });
    row.appendChild(btn);
    tbody.appendChild(row);
  }

  table.append(thead1, thead2, tbody);
  document.body.appendChild(table);

  // 购物车UI更新函数
  function updateCartDisplay(flights) {
    let cart = document.getElementById("flight-cart");
    if (!cart) {
      cart = document.createElement("div");
      cart.id = "flight-cart";
      cart.innerHTML = "<h3>购物车</h3>";
      document.body.appendChild(cart);
    }
    // 清空现有内容后重新渲染
    cart.innerHTML = "<h3>购物车</h3>";
    flights.forEach((flight, idx) => {
      let item = document.createElement("div");
      item.innerText = `${idx+1}. 航班${flight.flightNumber}: ${flight.departure} → ${flight.arrival}`;
      cart.appendChild(item);
    });
  }
}).catch(() => {
  document.write("加载航班数据失败")
});

关键修改说明

  • 异步逻辑修正:把购物车的添加、展示逻辑放在点击事件内部,确保只有用户点击后才执行,避免同步代码提前读取空数组。
  • 直接绑定航班数据:循环创建按钮时,直接把当前flight对象绑定到点击事件中,无需再通过ID索引查找,代码更简洁可靠。
  • 新增购物车UI:添加updateCartDisplay函数,点击按钮后实时更新页面上的购物车展示,满足你的需求。
  • 重复添加防护:加入判断逻辑,防止同一航班被多次添加到购物车(可根据需求移除)。

原代码空数组原因

原代码中,你创建完按钮绑定事件后,立刻将bookedFlights放入data对象返回,然后在下一个then里打印数组元素。这整个流程是同步执行的,此时用户还没有任何点击操作,数组自然为空。只有用户点击按钮后数组才会被填充,但这时then链已经执行完毕,所以你看不到后续添加的数据。

内容的提问来源于stack exchange,提问作者LearningCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 12:25:28