![](/img/trans.png)
[英]Tracking which list element has been clicked on and transferring this data into PHP
[英]From a rendered list of flights, how does one access the specific flight-data which relates to the flight's booking-button that has been clicked?
從獲取的航班數據項數組中,我能夠創建一個表格,其中每一行都顯示其特定的航班數據,旁邊還有一個用於預訂相關航班的按鈕。
我想將每個按鈕添加到一個數組中,以便我可以使用該數組來1)訪問當前預訂的航班和2)添加/顯示它到購物車/在購物車上。
我遇到的問題是數組bookedFlights
永遠不會被附加,所以我無法訪問已單擊以供稍后使用的按鈕。
如何訪問與已單擊按鈕相關的特定航班數據?
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 bookingButtons = [];
let row1 = document.createElement("tr");
let row2 = document.createElement("tr");
let headingTH = document.createElement("th");
headingTH.innerText = "Available Flights";
headingTH.colSpan = 7;
row1.appendChild(headingTH);
thead1.appendChild(row1);
for (key in fakeFlights[0]) {
let heading = document.createElement("th");
if (key === "flightNumber") {
key = "Flight Number"
}
if (key === "departureTime") {
key = "Departure Time"
}
if (key === "arrivalTime") {
key = "Arrival Time"
}
heading.innerText = key;
row2.appendChild(heading);
}
let heading = document.createElement("th");
heading.innerText = "Book the flight";
row2.appendChild(heading);
thead2.appendChild(row2);
for (let i = 0; i < fakeFlights.length; i++) {
let row = document.createElement("tr");
for (key in fakeFlights[i]) {
let rowData = document.createElement("td");
rowData.innerHTML = fakeFlights[i][key];
row.appendChild(rowData);
}
let btn = document.createElement("button");
btn.innerText = "Book";
btn.id = i;
bookingButtons.push(btn);
row.appendChild(btn);
tbody.appendChild(row);
}
table.append(thead1, thead2, tbody);
document.body.appendChild(table);
let bookedFlights = [];
for (let selectedButton of bookingButtons) {
selectedButton.addEventListener("click", function() {
bookedFlights.push(selectedButton.id);
});
}
const data = {
flights: fakeFlights,
bookedFlights: bookedFlights
}
return data;
}).then((data) => {
console.log(data.flights[data.bookedFlights[0]]);
}).catch(() => {
document.write("error")
});
兩種主要的改進模式/技術是……
事件委托,對於 OP 提供的環境意味着,必須在table
相關元素節點或更好的情況下在表體的相關元素節點注冊一個事件偵聽器,因為后者是所有與航班相關的表數據。
關注點分離是另一個。 在其最基本的實現中,針對 OP 最初提供的代碼,這意味着每個正確命名的 function 語句...
fetchAndDisplayFlightData
),createFlightOverview
),handleBookingOfSelectedFlight...
),... 任務。
最終實現具有以下技術/方法......
fetchAndDisplayFlightData
期望和 URL 從中fetch
飛行數據。 在此 function 中,通過將響應數據的flights
數組傳遞給 createFlightOverview 來創建航班數據概覽,此處為createFlightOverview
表元素。
后者 function 主要通過 OP 最初提供的代碼處理此航班列表( listOfFlights
)。 雖然有一些改進,比如......
...使用基於 object 的headerContentLookup
以便通過每個數據項的鍵訪問正確的表 header 內容。
...為每個呈現的數據項的“預訂”按鈕使用全局data-*
屬性data-flight-number
及其相關的dataset
屬性flightNumber
號,因為后者正是標識航班(或航班數據物品)。
如前所述,只有一個'click'
處理程序將在表元素的表體元素中注冊。 非常處理程序 function 實現this
上下文感知,因此它期望綁定一個Map
。 后者的數據由助手 function ( createFlightNumberBasedFlightDataMap
) 創建,它根據每個航班數據項的flightNumber
值執行map
響應數據的flights
數組,該值用作航班項目的標識符key
。
// - the OP's own originally provided (most of it) table creation code. function createFlightOverview(listOfFlights) { const headerContentLookup = { departureTime: 'Departure Time', arrivalTime: 'Arrival Time', flightNumber: 'Flight Number', destination: 'Destination', origin: 'Origin', price: 'Price', }; const table = document.createElement("table"); const thead1 = document.createElement("thead"); const thead2 = document.createElement("thead"); const tbody = document.createElement("tbody"); // - not needed. // const bookingButtons = []; const row1 = document.createElement("tr"); const row2 = document.createElement("tr"); const headingTH = document.createElement("th"); headingTH.textContent = "Available Flights"; headingTH.colSpan = 7; row1.appendChild(headingTH); thead1.appendChild(row1); Object.keys(listOfFlights[0]).forEach(key => { const heading = document.createElement("th"); heading.textContent = headerContentLookup[key]?? key; row2.appendChild(heading); }); const heading = document.createElement("th"); heading.textContent = "Book the flight"; row2.appendChild(heading); thead2.appendChild(row2); listOfFlights.forEach(flightItem => { const row = document.createElement("tr"); Object.values(flightItem).forEach(value => { const cellData = document.createElement("td"); cellData.textContent = value; row.appendChild(cellData); }); const btn = document.createElement("button"); btn.textContent = "Book"; // - not recommended. // btn.id = i; // - for the flight identification rather use // a data-item's `flightNumber` provided as // global `data-*` attribute... like eg btn.dataset.flightNumber = flightItem.flightNumber; // - not needed. // bookingButtons.push(btn); row.appendChild(btn); tbody.appendChild(row); }); table.append(thead1, thead2, tbody); return table; } // - helper task which creates a `Map` instance from an array of flight // related data-items, based on each item's `flightNumber` value. function createFlightNumberBasedFlightDataMap(listOfFlights) { return new Map( listOfFlights.map(flightItem => [flightItem.flightNumber, flightItem]) ) } // - the final task which actually is going to trigger the // booking-process for the before selected flight-item. function bookSelectedFlight(flightData) { console.log({ selectedFlightData: flightData }); } // - the handler function which is aware of a bound `this` context // where `this` refers to the one time created (and bound) // flight number based lookup. function handleBookingOfSelectedFlightFromBoundFlightDataMap({ target }) { const flightDataMap = this; const elmButton = target.closest('button'); if (elmButton) { const { flightNumber } = elmButton.dataset?? null; const selectedFlightData = flightDataMap.get(flightNumber); console.log({ elmButton, flightNumber/*, selectedFlightData*/ }); bookSelectedFlight(selectedFlightData); } } // - the OP's provided example code changed according to the suggestions. function fetchAndDisplayFlightData(url) { return fetch(url).then(response => response.json()).then(flightData => { const listOfFlights = flightData.flights; const flightOverview = createFlightOverview(listOfFlights); // - register the button specific click-handling at the table's body. flightOverview.querySelector('tbody').addEventListener( 'click', // - create a handler function which has a flight number based // `Map` instance as lookup table bound to its `this` context. handleBookingOfSelectedFlightFromBoundFlightDataMap.bind( createFlightNumberBasedFlightDataMap(listOfFlights) ) ); document.body.appendChild(flightOverview); }).catch(reason => document.body.appendChild(document.createTextNode(String(reason))) ); } fetchAndDisplayFlightData( 'https://mocki.io/v1/fa695c4b-475e-4dfc-8608-952c0c5a28b5' );
body { margin: 0 0 100px 0; zoom: .9; }.as-console-wrapper { max-height: 100px;important; }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.