如何用Bootstrap Table展示后端API返回数据?求嵌套循环建表指引
Hey there! Let's get your Pokemon data displayed in a table using Bootstrap Table first, then I'll walk through manual table creation with nested loops, plus share some tips on learning that pattern.
1. Display Data with Bootstrap Table
First, you'll need to add Bootstrap Table's CSS and JS to your frontend (it works seamlessly with your existing Bootstrap 3 setup). Here's the updated frontend code:
Updated Frontend Code
<!DOCTYPE html> <html lang="en"> <head> <title>Pokemon Pokedex</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <!-- Bootstrap Table CSS --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.18.3/bootstrap-table.min.css"> </head> <body> <div class="container"> <h1>Gen 1 Pokemon Pokedex</h1> <!-- Table container --> <table id="pokemon-table" class="table table-striped"></table> </div> <!-- jQuery --> <script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script> <!-- Bootstrap JS --> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <!-- Bootstrap Table JS --> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.18.3/bootstrap-table.min.js"></script> <script type="text/javascript"> $(document).ready(function() { $.get("http://localhost:3000/pokemon", function(data, status) { console.log("Data loaded:", status); // Initialize Bootstrap Table with your data $('#pokemon-table').bootstrapTable({ data: data, columns: [ { field: 'id', title: 'ID', sortable: true }, { field: 'name', title: 'Pokemon Name', sortable: true }, { field: 'type', title: 'Type' }, { field: 'immuneTo', title: 'Immune To' }, { field: 'weakTo', title: 'Weak To' }, { field: 'evolutionName', title: 'Evolution' } ] }); }); }); </script> </body> </html>
Key Notes:
- The
columnsarray maps your API's data fields to table headers—customize this list to show only the fields you care about - Bootstrap Table automatically handles styling, sorting, and basic pagination, so you don't have to build all that from scratch
2. Manual Table Creation with Nested Loops
If you want to build the table entirely on your own without the plugin, here's how to use nested loops to generate rows and columns:
Updated Frontend Script (Replace your existing script block)
$(document).ready(function() { $.get("http://localhost:3000/pokemon", function(data, status) { console.log("Data loaded:", status); // Define which fields and headers we want to display const tableFields = ['id', 'name', 'type', 'immuneTo', 'weakTo', 'evolutionName']; const tableHeaders = ['ID', 'Pokemon Name', 'Type', 'Immune To', 'Weak To', 'Evolution']; // Create the base table element with Bootstrap classes const $table = $('<table>').addClass('table table-striped'); const $thead = $('<thead>').appendTo($table); const $tbody = $('<tbody>').appendTo($table); // Build header row (outer loop for headers) const $headerRow = $('<tr>').appendTo($thead); tableHeaders.forEach(header => { $('<th>').text(header).appendTo($headerRow); }); // Build data rows (outer loop for each Pokemon entry) data.forEach(pokemon => { const $row = $('<tr>').appendTo($tbody); // Inner loop for each field in the Pokemon object tableFields.forEach(field => { // Use 'N/A' if the field has no value $('<td>').text(pokemon[field] || 'N/A').appendTo($row); }); }); // Add the finished table to the page $('.container').append($table); }); });
How the Nested Loops Work:
- Outer Loop: Iterates over each Pokemon object in your
dataarray, creating a new table row for each entry - Inner Loop: Iterates over the predefined fields, creating a table cell for each piece of data in the row
- Using explicit field lists keeps your table clean and avoids showing unexpected database columns
3. Learning Nested Loops for Table Creation
To master this pattern, focus on these core concepts:
- Start with static mock data (e.g., an array of sample Pokemon objects) to practice loops without relying on your API
- Always define the fields/headers you want to display explicitly—this makes your code easier to maintain and avoids messy tables
- Understand the DOM hierarchy:
table→thead/tbody→tr→th/td - Practice both jQuery-based DOM creation (like the example above) and vanilla JS (using
document.createElement) to build familiarity
Your Backend Code (Formatted & Secured)
const mysql = require('mysql'); const express = require('express'); const bodyParser = require('body-parser'); const app = express(); var urlencodedParser = bodyParser.urlencoded({ extended: false }); // Pokemon Database Connection var conPoke = mysql.createConnection({ host: "localhost", user: "root", password: "", database: "classnew" }); conPoke.connect(function(err) { if (err) throw err; }); // CORS Middleware app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); // Routes app.get('/', (req, res) => res.send('Welcome to my Pokemon API. We are using only gen 1 pokemon here! Use localhost:3000/pokemon to view your pokedex!')); app.get('/pokemon', function(req, res) { console.log("--POKEDEX CONNECTED!"); conPoke.query("SELECT * FROM pokemon", function(err, result) { if (err) throw err; res.json(result); }); }); app.post('/pokemon', urlencodedParser, function(req, res) { const { name, type, immuneTo, strongResist, resists, weakTo, veryWeakTo, evolutionName } = req.body; // Use parameterized queries to prevent SQL injection conPoke.query( "INSERT INTO pokemon (name, type, immuneTo, strongResist, resists, weakTo, veryWeakTo, evolutionName) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [name, type, immuneTo, strongResist, resists, weakTo, veryWeakTo, evolutionName], function(err, result) { if (err) throw err; console.log("----SUBMITTED!"); res.redirect('/pokemon'); } ); }); app.get('/pokemon/:id', function(req, res) { var id = req.params.id; conPoke.query("SELECT * FROM pokemon WHERE id = ?", [id], function(err, result) { if (err) throw err; res.json(result); console.log("-----" + JSON.stringify(result)); }); }); app.get('/pokemon/del/:id', function(req, res) { var delID = req.params.id; conPoke.query("DELETE FROM pokemon WHERE id = ?", [delID], function(err, result) { if (err) throw err; console.log("------REMOVED!"); }); res.redirect('/pokemon'); }); app.listen(3000, () => console.log('-WELCOME'));
Note: I updated your backend's SQL queries to use parameterized queries (the ? placeholders) instead of string concatenation—this prevents SQL injection attacks, which is a critical security best practice!
内容的提问来源于stack exchange,提问作者Ext-

