点此查看 所有教程、项目、源码导航
文章目录
- 1. 本篇任务说明
- 2. 调整HTML表格与弹窗,准备编辑功能
- 3. 新增状态标记变量、编辑函数
- 4. 修改【新增按钮】的打开弹窗逻辑
- 5. 修改提交函数:判断新增/编辑,调用不同接口
- 6. 功能测试流程梳理
- 7. 本篇小结
- 8. 下一节预告
1. 本篇任务说明
毛哥:副队,上一篇我们做完了查询、新增、删除,还差编辑活动对吧? 副队:没错!这一篇我们来实现编辑修改活动。编辑和新增用同一个弹窗,这是开发里很常见的复用思路,不用重新写一套弹窗HTML。 毛哥:同一个弹窗,那怎么区分我现在是新增,还是编辑? 副队:我们用一个变量标记状态。打开弹窗的时候,如果是编辑,我们先调用接口拿到这条活动的详情,把原有数据回填到表单输入框里;提交的时候,判断是新增还是编辑,调用不同的后端接口。 毛哥:懂了!新增的时候表单是空的,编辑的时候表单里面自动填好原来的信息,改完再提交。
我们沿用之前的文件结构,所有文件放在同一目录:
├── common.css
├── activity-manage.css
├── common.js
├── activity-manage.js
└── activity-manage.html
副队:还有一个细节,我看你打开弹窗直接写 style.display='flex',其实可以通过添加 .show 类来控制弹窗显示隐藏,这样代码更加规范。 毛哥:好嘞,这个地方我记牢,以后不再直接改display了。 副队:没事,这两种写法都是可以正常运行的,采用class控制更加规范一些。
2. 调整HTML表格与弹窗,准备编辑功能
副队:首先我们先改HTML,表格的操作列增加【编辑】按钮,绑定编辑函数,把活动id传进去。弹窗结构不用新增,就复用之前的editMask弹窗。 毛哥:弹窗标题也要变,新增的时候显示“新增活动”,编辑的时候显示“编辑活动”,这个我们用JS动态改标题文本就行。
找到 activity-manage.js 里getActivityList函数,修改如下:
tr.innerHTML = `
<td>${item.id}</td>
<td>${item.name}</td>
<td>${item.type}</td>
<td>${item.time}</td>
<td>${item.address}</td>
<td>${item.endTime}</td>
<td>${item.maxNum}</td>
<td>${item.about}</td>
<td>
<button class="btn btn-del" onclick="delActivity(${item.id})">删除</button>
<button class="btn btn-edit" onclick="editActivity(${item.id})">编辑</button>
<button class="btn btn-list" onclick="viewNameList(${item.id})">查看报名名单</button>
</td>
`;
弹窗标题加上id,方便JS修改文字:
<h3 id="maskTitle">新增活动</h3>
3. 新增状态标记变量、编辑函数
副队:我们在activity-manage.js顶部定义两个全局变量:一个标记弹窗模式,一个保存当前正在编辑的活动id。 毛哥:全局变量?放在外面,所有函数都能读到对吧? 副队:对,适合这个简单项目。isEdit 为false代表新增模式,true代表编辑模式;editId 保存当前编辑的活动id,新增的时候这个值没用。
在 activity-manage.js 最上方添加:
// 标记弹窗模式:false=新增,true=编辑
let isEdit = false;
// 保存当前编辑的活动id
let editId = null;
// 获取弹窗元素
const editMask = document.getElementById('editMask');
const maskTitle = document.getElementById('maskTitle');
然后编写 editActivity 函数:点击编辑按钮触发,根据id查询详情,回填表单。
// 打开编辑弹窗,回显活动数据
function editActivity(id) {
// 切换为编辑模式
isEdit = true;
editId = id;
maskTitle.innerText = "编辑活动";
// 调用详情接口,拿到这条活动完整信息
postRequest('/activity/detail', {id: id}, function(res) {
if(res.code === 200) {
let data = res.data;
// 把后端返回的数据回填到各个输入框
document.getElementById('name').value = data.name;
document.getElementById('type').value = data.type;
document.getElementById('time').value = data.time;
document.getElementById('address').value = data.address;
document.getElementById('endTime').value = data.endTime;
document.getElementById('maxNum').value = data.maxNum;
document.getElementById('about').value = data.about;
// 添加show类,显示弹窗
editMask.classList.add('show');
} else {
alert(res.msg);
}
})
}
此时点击编辑,效果如下,注意数据是从后端带回来的最新数据。 
4. 修改【新增按钮】的打开弹窗逻辑
副队:原来新增按钮打开弹窗的代码也要改,打开新增弹窗的时候,重置标记、清空表单、改标题。 毛哥:不然上次编辑的数据留在输入框里,点新增的时候,里面还有旧数据,就bug了!
修改新增按钮点击事件:
// 新增按钮,打开弹窗
document.getElementById('btnAdd').onclick = function () {
// 切换为新增模式
isEdit = false;
editId = null;
maskTitle.innerText = "新增活动";
// 清空所有表单输入框
document.getElementById('name').value = '';
document.getElementById('type').value = '';
document.getElementById('time').value = '';
document.getElementById('address').value = '';
document.getElementById('endTime').value = '';
document.getElementById('maxNum').value = '';
document.getElementById('about').value = '';
// 显示弹窗
editMask.classList.add('show');
}
取消按钮也同步修改,用classList移除show:
// 取消弹窗按钮
document.getElementById('btnCancel').onclick = function () {
editMask.classList.remove('show');
}
毛哥:这样明显更合理了,新增的时候会清除之前表单的数据,而更改的时候自动带入之前的信息,又学了一招,太厉害啦。
5. 修改提交函数:判断新增/编辑,调用不同接口
副队:重点来了!同一个提交按钮,根据 isEdit 判断走哪个接口。 毛哥:新增走 /activity/add,编辑走 /activity/update,编辑的时候还要把id一起传给后端,对吧? 副队:没错。后端接收update接口的时候,必须拿到活动id,才能知道要修改数据库里哪一条记录。校验逻辑和新增保持一致,同样做非空判断。
改造 submitAddActivity 函数,改名为 submitActivity:
// 提交表单(新增 / 修改共用这一个函数)
function submitActivity() {
// 获取表单输入值
let name = document.getElementById('name').value;
let type = document.getElementById('type').value;
let time = document.getElementById('time').value;
let address = document.getElementById('address').value;
let endTime = document.getElementById('endTime').value;
let maxNum = document.getElementById('maxNum').value;
let about = document.getElementById('about').value;
// 前端非空校验
if (!name || !type || !time || !address || !endTime || !maxNum || !about) {
alert('请填写全部活动信息!');
return;
}
// 组装参数
let params = {
name: name,
type: type,
time: time,
address: address,
endTime: endTime,
maxNum: maxNum,
about: about
}
// 判断是新增还是编辑
if(isEdit) {
// 编辑模式,带上id
params.id = editId;
postRequest('/activity/update', params, function(res) {
if (res.code === 200) {
alert('修改活动成功!');
editMask.classList.remove('show');
getActivityList();
} else {
alert(res.msg);
}
})
} else {
// 新增模式
postRequest('/activity/add', params, function(res) {
if (res.code === 200) {
alert('新增活动成功!');
editMask.classList.remove('show');
getActivityList();
} else {
alert(res.msg);
}
})
}
}
// 提交按钮绑定共用的提交方法
document.getElementById('btnSubmit').onclick = submitActivity;
此时咱们点击新增后提交,就会调用后台新增接口,然后刷新界面数据。点击编辑后提交,就会调用后台编辑接口,然后刷新界面数据。
6. 功能测试流程梳理
副队:我们梳理一遍完整流程,看看逻辑通不通:
毛哥:哇,一个弹窗复用两个功能,代码少写好多,这个思路太妙了! 副队:这就是前端开发很常用的弹窗复用技巧,很多后台管理系统都是这么写的。
7. 本篇小结
副队:到这里,管理员这边活动的**增、删、改、查(CRUD)**全部做完了。 毛哥:太有成就感了!查询、新增、修改、删除一套流程跑通,后端数据库的数据我们前端都能控制了。 副队:没错。但是咱们还有一个功能没做:【查看报名名单】按钮,点击弹窗展示这个活动所有报名学生。做完这个,管理员端的功能就全部完成了。
8. 下一节预告
毛哥:那下一篇我们做什么? 副队:下一篇我们实现【查看报名名单弹窗】,对接报名列表接口,完成管理员端最后的功能。管理员端全部做完之后,我们就开始开发学生端页面。
网硕互联帮助中心






评论前必须登录!
注册