实战案例:
mysql数据库的info01表中,有如下字段:kmz、chengci、yxid、yxname、zyid、zyname、jhs、xz、xf。
我现在写了如下微信小程序的wxml代码:
<button bindtap="filterData" style="width: 100%; margin-top: 28rpx; background-color: lightslategrey; color: white; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);">立即筛选</button>
<view wx:for="{
{pathinfo}}" class="view1" wx:if="{
{!loading}}">
<view class="view-box1">
<view class="view-box2">
<view class="title0">
<view class="title11">
<view class="cc1"><view class="cc2">{
{item.chengci}}</view></view>
<view>{
{item.yxname}}</view>
</view>
</view>
</view>
<view>
<view class="view-box3">
<view>
<h1>科目:</h1><h1>{
{item.kmz}}</h1>
</view>
<view class="view-boxright">
<h1>专业名:</h1><h1>{
{item.zyname}}</h1>
</view>
</view>
<view class="view-box3">
<view><h1>计划数:</h1><h1>{
{item.jhs}}</h1></view>
<view class="view-boxright"><h1>学费:</h1><h1>{
{item.xf}}</h1></view>
<view class="view-boxright"><h1>学制:</h1><h1>{
{item.xz}}</h1></view>
</view>
</view>
</view>
</view>
当用户点击bindtap="filterData"事件后,会调用微信小程序TS文件中的下列代码:
filterData: function() {
this.setData({
loading: true,
offset: 0, // 重置已加载的数据量
pathinfo: [], // 清空现有数据
hasMore: true, // 重置是否还有更多数据标志
});
this.loadData();
},
loadData: function () {
if (!this.data.hasMore) return; // 如果没有更多数据,则不执行加载操作
wx.showLoading({
title: '加载中...',
});
const year = this.data.years[this.data.yearIndex];
const batch = this.data.batches[this.data.batchIndex];
const limit = this.data.limit;
const offset = this.data.offset;
console.log("选择器",year, batch);
this.setData({
loading: true
});
wx.request({
url: config.apiUrl + '/api/getinfojh',
method: 'POST',
data: {
year: year,
batch: batch,
limit: limit, // 新增,传递每次加载的数据量
offset: offset, // 新增,传递当前已加载的数据量
},
header: {
'content-type': 'application/json' // 确保发送的是JSON格式
},
success: (res) => {
if (res.statusCode === 200) {
const newData = res.data;
const allData = this.data.pathinfo.concat(newData);
this.setData({
//pathinfo: res.data,
pathinfo: allData,
offset: offset + newData.length, // 更新已加载的数据量
hasMore: newData.length === limit, // 如果返回的数据少于请求的数据量,则表示没有更多数据
loading: false
});
wx.pageScrollTo({
scrollTop: 99999, // 给一个足够大的值,确保可以滚动到底部
duration: 0 // 滚动动画持续时间,单位ms
});
} else {
// 处理错误情况,例如无数据或查询错误
this.setData({
pathinfo: [],
loading: false
});
wx.showToast({
title: '未找到数据',
icon: 'none'
});
}
wx.hideLoading();
},
fail: (err) => {
console.error(err);
this.setData({
loading: false
});
wx.hideLoading();
wx.showToast({
title: '数据加载失败',
icon: 'none'
});
}
});
},
然后通过下面/api/getinfojh路由接口获取数据:
const express = require('express');
const router = express.Router();
const sql = require('../sql');
router.post('/getinfojh', function(req, res, next) {
//const { year, batch } = req.body;
const { year, batch, limit, offset } = req.body;
console.log(year, batch);
let tableName = '';
// 确保参数匹配的逻辑是正确的
if (year === '2022' && batch === '第一批次') {
tableName = 'info01';
console.log(tableName);
} else if (year === '2022' && batch === '第二批次') {
tableName = 'info02';
console.log(tableName);
} else if (year === '2023' && batch === '第一批次') {
tableName = 'info03';
console.log(tableName);
} else if (year === '2023' && batch === '第二批次') {
tableName = 'info05';
console.log(tableName);
} else {
// 如果没有匹配的表,返回错误
return res.status(400).json({ message: 'Invalid year or batch' });
}
// 查询数据库前打印SQL语句
console.log(`SELECT * FROM ${tableName}`);
// 修改SQL查询语句,增加LIMIT和OFFSET子句
const query = `SELECT * FROM ${tableName} LIMIT ${limit} OFFSET ${offset}`;
//const query = `SELECT *, COUNT(*) as count FROM ${tableName} GROUP BY yxname LIMIT ${limit} OFFSET ${offset}`;
//SELECT yxname FROM info01 GROUP BY yxname HAVING COUNT(*) > 1;
//const query = `SELECT DISTINCT yxname,chengci FROM ${tableName} LIMIT ${limit} OFFSET ${offset}`;
//SELECT DISTINCT yxname FROM info;这个查询会检索info表中的yxname列,并且只返回不重复的值。如果yxname列中有重复的值,它们只会在结果集中出现一次。
console.log(query);
// 查询数据库
sql.query(query, (err, result) => {
if (err) {
console.error("查询出现错误:", tableName);
console.error(err);
res.status(500).json({ message: 'Internal Server Error' });
} else {
// 确保返回的结果是预期的
if (result.length > 0) {
res.json(result);
//res.status(200).json(result);
console.log("返回了结果");
} else {
// 如果查询结果为空,返回404状态码
console.log("查询结果为空");
res.status(404).json({ message: 'No data found' });
}
}
});
});
module.exports = router;
最后将获得到的数据显示到下面的代码中:
<view wx:for="{
{pathinfo}}" class="view1" wx:if="{
{!loading}}">
<view class="view-box1">
<view class="view-box2">
<view class="title0">
<view class="title11">
<view class="cc1"><view class="cc2">{
{item.chengci}}</view></view>
<view>{
{item.yxname}}</view>
</view>
</view>
</view>
<view>
<!-- <view wx:for="{
{pathinfos}}"> -->
<view class="view-box3">
<view>
<h1>科目:</h1><h1>{
{item.kmz}}</h1>
</view>
<view class="view-boxright">
<h1>专业名:</h1><h1>{
{item.zyname}}</h1>
</view>
</view>
<view class="view-box3">
<view><h1>计划数:</h1><h1>{
{item.jhs}}</h1></view>
<view class="view-boxright"><h1>学费:</h1><h1>{
{item.xf}}</h1></view>
<view class="view-boxright"><h1>学制:</h1><h1>{
{item.xz}}</h1></view>
</view>
</view>
</view>
</view>
现在我想要将info01表中yxname字段值相同的数据,遍历后显示到下面的代码中:
<view class="view-box3">
<view>
<h1>科目:</h1><h1>{
{item.kmz}}</h1>
</view>
<view class="view-boxright">
<h1>专业名:</h1><h1>{
{item.zyname}}</h1>
</view>
</view>
于是我写了/api/getinfojh2路由接口,代码如下:
const express = require('express');
const router = express.Router();
const sql = require('../sql');
router.post('/getinfojh2', function(req, res, next) {
const { year, batch, yxname } = req.body;
let tableName = '';
// 根据年份和批次确定表名
if (year === '2022' && batch === '第一批次') {
tableName = 'info01';
} else if (year === '2022' && batch === '第二批次') {
tableName = 'info02';
} else if (year === '2023' && batch === '第一批次') {
tableName = 'info03';
} else if (year === '2023' && batch === '第二批次') {
tableName = 'info05';
} else {
return res.status(400).json({ message: 'Invalid year or batch' });
}
// 查询数据库,获取特定yxname对应的所有记录
const query = `SELECT * FROM ${tableName} WHERE yxname = ?`;
sql.query(query, [yxname], (err, result) => {
if (err) {
console.error("查询出现错误:", err);
res.status(500).json({ message: 'Internal Server Error' });
} else {
if (result.length > 0) {
res.json(result);
} else {
res.status(404).json({ message: 'No data found for the specified yxname' });
}
}
});
});
module.exports = router;
现在我想要将getinfojh2路由接口,用wx.request语句放置在getinfojh路由接口后进行调用,让每一个<view wx:for="{ {pathinfo}}" class="view1" wx:if="{ {!loading}}">块都能显示指定yxname字段值的所有内容,并将相同yxname字段值的内容,遍历显示在下面的代码中:
<view class="view-box3">
<view>
<h1>科目:</h1><h1>{
{item.kmz}}</h1>
</view>
<view class="view-boxright">
<h1>专业名:</h1><h1>{
{item.zyname}}</h1>
</view>
</view>
解决方案如下:
将getinfojh2路由接口的调用,放置在getinfojh路由接口的成功回调函数中。以下是修改后的代码示例:
if (res.statusCode === 200) {
const newData = res.data;
const allData = this.data.pathinfo.concat(newData);
// 添加调用getinfojh2路由接口的代码
for (let i = 0; i < allData.length; i++) {
const yxname = allData[i].yxname;
wx.request({
url: config.apiUrl + '/api/getinfojh2',
method: 'POST',
data: {
year: year,
batch: batch,
yxname: yxname
},
header: {
'content-type': 'application/json'
},
success: (res) => {
if (res.statusCode === 200) {
// 将获取到的数据更新到指定的allData项中
allData[i].yxInfo = res.data;
this.setData({
pathinfo: allData
});
} else {
console.log("未找到数据");
}
},
fail: (err) => {
console.error(err);
console.log("数据加载失败");
}
});
}
this.setData({
pathinfo: allData,
offset: offset + newData.length,
hasMore: newData.length === limit,
loading: false
});
// 其他代码...
} else {
// 处理错误情况...
}
wx.hideLoading();
},
然后,在WXML代码中通过wx:for和使用item.yxInfo获取到每个yxname字段值对应的数据,并将其遍历显示在相应的<view class="view-box3">块中:
<view wx:for="{
{pathinfo}}" class="view1" wx:if="{
{!loading}}">
<view class="view-box1">
<view class="view-box2">
<view class="title0">
<view class="title11">
<view class="cc1"><view class="cc2">{
{item.chengci}}</view></view>
<view>{
{item.yxname}}</view>
</view>
</view>
</view>
<view>
<!-- 遍历显示指定yxname字段值的内容 -->
<view class="view-box3" wx:for="{
{item.yxInfo}}">
<view>
<h1>科目:</h1><h1>{
{item.kmz}}</h1>
</view>
<view class="view-boxright">
<h1>专业名:</h1><h1>{
{item.zyname}}</h1>
</view>
</view>
<view class="view-box3">
<view><h1>计划数:</h1><h1>{
{item.jhs}}</h1></view>
<view class="view-boxright"><h1>学费:</h1><h1>{
{item.xf}}</h1></view>
<view class="view-boxright"><h1>学制:</h1><h1>{
{item.xz}}</h1></view>
</view>
</view>
</view>
</view>
这样,每个<view wx:for="{ {pathinfo}}" class="view1" wx:if="{ {!loading}}">块都会根据指定的yxname字段值显示对应的内容。