JavaWeb - 黑马旅游网(番外3):取消收藏
黑马旅游网(番外3):取消收藏
1 功能描述
接上篇黑马旅游网(番外2):用户收藏分页展示,在本篇博客中,我将实现另一个与收藏相关的功能:取消收藏。
原始的旅游详情页面只有一个 点击收藏
的按钮。在我的实现方式中:在 点击收藏
旁边添加了一个 取消收藏
的按钮,两个按钮的样式相反。当用户没有登录或登录后没有收藏此线路,则 点击收藏
为红色且可点击,取消收藏
为灰色且不可点击;反之亦然。
2 功能分析
2.1 前端
实现取消收藏,前端的重点在于对两个按钮状态的切换。在黑马旅游网(8):旅游线路收藏中,添加收藏
按钮的状态切换是采用 AJAX 方式实现,这种方式避免跳转页面,我在进一步开发时也是基于之前的代码:为 取消收藏
绑定单击事件,采用对仗的方式补充了取消收藏的代码。但是功能开发完毕后,这种异步请求只能满足一次请求有效,再次请求就必须刷新页面。例如:当点击 添加收藏
时,利用 AJAX 将两个按钮的状态做一次切换,但是再次点击请求失效。在此处,我的解决方式是每次单击事件结束前都刷新一次页面,保证添加和取消动作的连贯性。其它读者要是有更好的实现方式的话,欢迎私信/评论分享和讨论。
2.2 后端
相比前端,后端的执行逻辑比较清晰和简单了。在 Servlet 层获取 uid
和 rid
,然后依次传入 Service 层和 Dao 层执行具体的数据库删除业务即可。前台通过重新查询的方式更新页面,调用之前定义的相关代码即可。
3 代码实现
3.1 后端
3.1.1 Servlet
RouteServlet.java
/**
* 取消收藏
*/
public void removeFavorite(HttpServletRequest request, HttpServletResponse response) {
// 1.获取线路id
String rid = request.getParameter("rid");
// 2.获取用户id
User user = (User) request.getSession().getAttribute("user");
if (user == null) return; // 未登录无法收藏,直接跳出方法
int uid = user.getUid();
// 3.调用service执行添加收藏
favoriteService.remove(rid, uid);
}
3.1.2 Service
FavoriteServiceImpl.java
/**
* 取消收藏路线
* @param rid 旅游路线id
* @param uid 用户id
*/
@Override
public void remove(String rid, int uid) {
favoriteDao.remove(Integer.parseInt(rid), uid);
}
3.1.3 Dao
FavoriteDaoImpl.java
/**
* 删除收藏路线
* @param rid 旅游路线id
* @param uid 用户id
*/
@Override
public void remove(int rid, int uid) {
String sql = "DELETE FROM tab_favorite WHERE rid = ? AND uid = ?";
template.update(sql, rid, uid);
}
3.2 前端
前端的改动比较大,主要体现在页面加载以及两个按钮的单击事件处理上。
route_detail.html
- 页面加载
/** * 发送请求,判断用户是否收藏过该线路 */ $(function fun () { let rid = getParameter("rid"); $.get("route/isFavorite", {rid: rid}, function (flag) { if (flag) { // 用户已收藏 // 设置收藏按钮样式 <a class="btn already" disabled="disabled"> let favor_selector = $("#favorite"); favor_selector.addClass("already"); favor_selector.attr("disabled", "disabled"); favor_selector.removeAttr("onclick"); // 删除按钮点击事件 let cancel_favor_selector = $("#cancel_favorite"); cancel_favor_selector.removeClass("already"); cancel_favor_selector.removeAttr("disabled"); cancel_favor_selector.attr("onclick"); } else { // 用户未收藏 // 设置收藏按钮样式 <a class="btn already" disabled="disabled"> let favor_selector = $("#favorite"); favor_selector.removeClass("already"); favor_selector.removeAttr("disabled", "disabled"); favor_selector.attr("onclick"); // 删除按钮点击事件 let cancel_favor_selector = $("#cancel_favorite"); cancel_favor_selector.addClass("already"); cancel_favor_selector.attr("disabled"); cancel_favor_selector.removeAttr("onclick"); } }); });
- 点击收藏
/** * 点击收藏按钮触发方法 */ function addFavorite() { let rid = getParameter("rid"); // 1.判断用户是否登陆 $.get("user/findOne", {}, function (user) { if (user) { // 用户登陆 $.get("route/addFavorite", {rid: rid}, function () { }); // 按钮渲染更新方式1:刷新页面 // location.reload(); // 按钮渲染更新方式2:发送一个异步请求 $.get("route/isFavorite", {rid: rid}, function (flag) { if (flag) { // 用户已收藏 // 设置收藏按钮样式 <a class="btn already" disabled="disabled"> let favor_selector = $("#favorite"); favor_selector.addClass("already"); favor_selector.attr("disabled", "disabled"); favor_selector.removeAttr("onclick"); // 删除按钮点击事件 let cancel_favor_selector = $("#cancel_favorite"); cancel_favor_selector.removeClass("already"); cancel_favor_selector.removeAttr("disabled"); cancel_favor_selector.attr("onclick"); } else { // 用户未收藏 // 设置收藏按钮样式 <a class="btn already" disabled="disabled"> let favor_selector = $("#favorite"); favor_selector.removeClass("already"); favor_selector.removeAttr("disabled", "disabled"); favor_selector.attr("onclick"); // 删除按钮点击事件 let cancel_favor_selector = $("#cancel_favorite"); cancel_favor_selector.addClass("already"); cancel_favor_selector.attr("disabled"); cancel_favor_selector.removeAttr("onclick"); } }); $.get("route/findOne", {rid: rid}, function (route) { $("#favoriteCount").html("已收藏" + route.count + "次"); // 设置收藏次数 }); location.reload(); // AJAX只能保证一次请求是有效的,不刷一下的话无法保证动作的连贯性 } else { // 用户未登录 alert("您尚未登陆,请登录"); location.href = "http://localhost/travel/login.html"; } }) }
- 取消收藏
/** * 取消收藏按钮触发方法 */ function removeFavorite () { let rid = getParameter("rid"); // 1.判断用户是否登陆 $.get("user/findOne", {}, function (user) { if (user) { // 用户登陆 $.get("route/removeFavorite", {rid: rid}, function () { }); // 按钮渲染更新方式1:刷新页面 // location.reload(); // 按钮渲染更新方式2:发送一个异步请求 $.get("route/isFavorite", {rid: rid}, function (flag) { if (flag) { // 用户已收藏 // 设置收藏按钮样式 <a class="btn already" disabled="disabled"> let favor_selector = $("#favorite"); favor_selector.addClass("already"); favor_selector.attr("disabled", "disabled"); favor_selector.removeAttr("onclick"); // 删除按钮点击事件 let cancel_favor_selector = $("#cancel_favorite"); cancel_favor_selector.removeClass("already"); cancel_favor_selector.removeAttr("disabled"); cancel_favor_selector.attr("onclick"); } else { // 用户未收藏 // 设置收藏按钮样式 <a class="btn already" disabled="disabled"> let favor_selector = $("#favorite"); favor_selector.removeClass("already"); favor_selector.removeAttr("disabled", "disabled"); favor_selector.attr("onclick"); // 删除按钮点击事件 let cancel_favor_selector = $("#cancel_favorite"); cancel_favor_selector.addClass("already"); cancel_favor_selector.attr("disabled"); cancel_favor_selector.removeAttr("onclick"); } }); $.get("route/findOne", {rid: rid}, function (route) { $("#favoriteCount").html("已收藏" + route.count + "次"); // 设置收藏次数 }); location.reload(); // AJAX只能保证一次请求是有效的,不刷一下的话无法保证动作的连贯性 } else { // 用户未登录 alert("您尚未登陆,请登录"); location.href = "http://localhost/travel/login.html"; } }); };
4 相关链接
项目课程链接:https://www.bilibili.com/video/BV1CE411E7h4
完整课程连接:https://www.bilibili.com/video/BV1uJ411k7wy
《黑马旅游网》系列博客及笔者源码传送门:https://blog.csdn.net/xing123456jl/article/details/109173068