新峰商城是一个开源电子商务网站(SpringBoot项目),本文主要简述它的商品分类中三级联动功能的实现。
一、多层级联动效果的常见场景
二、三级联动或者更多层级的数据联动是常见交互方式,它可以提升用户体验,限制用户随意输入内容,规范用户提交的数据。例如电商网站收货地址编辑场景,在新增收货地址时,依次选择省、市、县、镇,最终确定收货地址所在的地区。
二、多层级数据联动实现原理和方式
二级联动的原理就是当下拉框中选择列表N的值发生改变时,下一级的下拉框中选择列表M也发生改变,下拉列表M中的所有数据与下拉列表N中值相对应,三级联动或多级联动 ,就是利用二级联动的原理,在第一级的内容发生改变时,第二级跟着改变,第三级跟着第二级改变。
三、分类三级联动页面基础样式的实现
新建coupling-test.html ,并引入基础的 js和css样式文件,主要代码如下所示:
html
<form action="" method="post">
<label>请选择分类</label>
<select id="levelOne" data-placeholder="请选择分类..."></select>
<select id="levelTwo" data-placeholder="请选择分类..."></select>
<select id="levelThree" data-placeholder="请选择分类..."></select>
</form>
定 义三个select下拉选择框,id属性分别是levelOne、levelTwo、levelThree。此页面主要实现三级联动的三个下拉列表框展示效果。
然后,在NewBeeMallGoodsCattegoryController类中新增一个方法,即在访问admin/coupling-test时返回此视图,并让页面显示,代码如下所示:
java
@GetMapping("/coupling-test")
public String couplingTest(HttpServletRequest request){
return "admin/coupling-test";
}
三、数据初始化
数据初始化即是给选择框配置数据 ,让用户进行选择,此时,并未进行联动功能实现, 一级分类显示商品的所有一级分类,二级分类选择框和三级分类选择框中的内容根据上级数据的变化而发生联动变化。
初始化时,一级分类选择框显示所有一级分类,二级分类选择框当前一级分类选择框中第一条分类数据的所有二级分类,同理,三级分类选择框显示当前二级分类选择框中第一条分类数据 的所有三级分类,因此,需要先修改控制器下的couplingTest()方法,在转发视图前,先获取初始化数据,再带数据转发视图到coupling-test.html页面,编码如下所示:
java
@GetMapping("/coupling-test")
public String couplingTest(HttpServletRequest request){
request.setAttribute("path","coupling-test");
//查询所有的一级分类
List<GoodsCategory> firstLevelCategories=NewBeeMallCategorySerivice
.selectBylevelAndParentIdsAndNumber(Collections.singletonList(01)
,newBeeMall_categoryLevelEnum.LEVEL_ONE.getLevel());
if(!CollectionUtils.isEmpty(firstLevelCategories)){
//查询一级分类列表中第一个实体的所有二级分类
List<GoodsCategory> secondLevelCategories=NewBeeMallCategorySerivice
.selectBylevelAndParentIdsAndNumber(Collections.singletonList(
firstLevelCategories.get(0).getCategoryId())
,newBeeMall_categoryLevelEnum.LEVEL_TWO.getLevel());
}
if(!CollectionUtils.isEmpty(secondLevelCategories)){
//查询二级分类中第一个实体的所有三级分类
List<GoodsCategory> thirdLevelCategories=NewBeeMallCategorySerivice
.selectBylevelAndParentIdsAndNumber(Collections.singletonList(
secondLevelCategories.get(0).getCategoryId())
,newBeeMall_categoryLevelEnum.LEVEL_THREE.getLevel());
}
request.setAttribute("firstLevelCategories",firstLevelCategories);
request.setAttribute("secondLevelCategories",secondLevelCategories);
request.setAttribute("thirdLevelCategories",thirdLevelCategories);
return "admin/coupling-test";
}
然后,更改前端模板代码,读取后端数据到页面中,并填充三个下拉列表框,主要代码如下所示:
html
<form action="" method="post">
<label>请选择分类</label>
<select id="levelOne" data-placeholder="请选择分类...">
<th:block th:unless="${null==firstLevelCategories}">
<!--非空判断-->
<th:block th:each="c : ${firstLevelCategories}">
<!--循环列表-->
<option th:value="${c.categoryId}" th:test="${c.categoryName}"></option>
</th:block>
</th:block>
</select>
<select id="levelTwo" data-placeholder="请选择分类...">
<th:block th:unless="${null==secondLevelCategories}">
<!--非空判断-->
<th:block th:each="c : ${secondLevelCategories}">
<!--循环列表-->
<option th:value="${c.categoryId}" th:test="${c.categoryName}"></option>
</th:block>
</th:block>
</select>
<select id="levelThree" data-placeholder="请选择分类...">
<th:block th:unless="${null==thirdLevelCategories}">
<!--非空判断-->
<th:block th:each="c : ${thirdLevelCategories}">
<!--循环列表-->
<option th:value="${c.categoryId}" th:test="${c.categoryName}"></option>
</th:block>
</th:block>
</select>
</form>
四、联动后端接口实现
当触发上级下拉列表框的change 事件时,需要重新发起请求获取当前分类的下级分类数据 ,并将这些内容重新赋值到select下拉列表框中。
后端需要新增一 个接口,功能为根据前端选择的分类ID获取此分类下的下级分类数据,如此分类为一级分类,则返回此分类下的所有二级分类和第一个二级分类下的所有三级分类,如此分类为二级分类,则返回所有此分类下所有三级分类。新增接口代码如下所示:
java
@RequestMapping(value="/categories/listForSelect",method=RequestMethod.GET)
@ReponseBody
public Result listForSelect(RequestParam("categoryId") long categoryId){
if(categoryId==null || categoryId<1){
return ResultGenerator.genFailResult("缺少参数! ");
}
GoodsCategory category= NewBeeMallCategorySerivice.getGoodsCategoryById(categoryId);
//即不是一级分类也不是二级分类则不返回数据
if(category==null ||
category.getCategoryLevel()==newbee_mall_categoryLevel.Enum.LEVEL_THREE.getLevel())
{ return ResultGenerator.genFailResult("参数异常! ");}
Map categoryResult=new HashMap(2);
if(category.getCategoryLevel()==newbee_mall_categoryLevel.Enum.LEVEL_ONE.getLevel())
{
//如果是一级分类,则返回二级和三级
//查询一级分类列表中第一个实体和所有二级分类
List<GoodsCategory> secondLevelCategories=NewbeeMallCategoryService.selectByLevelAndParentIdsAndNumber(collections.singletonList(categoryId),newbee_mall_categoryLevelEnum.LEVEL_TWO_getLevel());
if(!CollectionsUtils.isEmpty(secondLevelCategories)){
//查询二级分类列表中第一个实体所有三级分类
List<GoodsCategory> thirdLevelCategories=NewbeeMallCategoryService.selectByLevelAndParentIdsAndNumber(collections.singletonList(secondLevelCategories.get(0).getCategoryId()),newbee_mall_categoryLevelEnum.LEVEL_THREE_getLevel());
categoryResult.put("secondLevelCategories",secondLevelCategories);
categoryResult.put("thirdLevelCategories",thirdLevelCategories);
}
}
if(category.getCategoryLevel()==newbee_mall_categoryLevel.Enum.LEVEL_TWO.getLevel())
{
//如果是二级分类则返回分类下所有三级类
List<GoodsCategory> thirdLevelCategories=NewbeeMallCategoryService.selectByLevelAndParentIdsAndNumber(collections.singletonList(categoryId),newbee_mall_categoryLevelEnum.LEVEL_THREE_getLevel());
categoryResult.put("thirdLevelCategories",thirdLevelCategories);
}
return ResultGenerator.getSuccessResult(categoryResult);
}
五、监听选择框的 change 事件并实现联动功能
接口实现后,需要处理前端交互,当选择框的 change 事件触发时,首先获取当前选择的分类id,并且根据此id 请求后端获取此分类下的下级分类数据,然后根据后端的分类列表数据重新拼装选择框中的option列表内容,最终完成联动效果。过程如下所示:
- 触发下拉选择框的change事件
- 获取当前选中的分类id
- 向listForSelect 接口请求下级分类数据
- 动态拼装option 列表
- 使用新的option列表内容并赋值给下拉选择框
其主要实现代码如下所示
javascript
$('#levelOne').on('change',function(){
$.ajax({
url: '/admin/categories/listForSelect?categoryId'+$(this.val()),
type: 'GET',
success: function(result){
if(result.resultCode==200){
var levelTwoSelect='';
var secondLevelCategories=result.data.secondLevelCategories;
var length2=secondLevelCategories.length;
for(var i=0; i<length2; i++){
levelTwoSelect+='<option value=\"'+secondLevelCategories[i].categoryId+'\">'+secondLevelCategories[i].categoryName+'</option>';
}
$('#levelTwo').html(levelTwoSelect);
var levelThreeSelect='';
var thirdLevelCategories=result.data.thirdLevelCategories;
var length3=thirdLevelCategories.length;
for(var i=0; i<length3; i++){
levelThreeSelect+='<option value=\"'+thirdLevelCategories[i].categoryId+'\">'+thirdLevelCategories[i].categoryName+'</option>';
}
$('#levelThree').html(levelThreeSelect);
} else {
swal(result.message,{icon: "error"});
};
},
error: function(){
swal("操作失败",{icon: "error"});
}
});
});
编码完成后,启动项目,启动成功后,在浏览器中输入如下请求地址,
html
http://localhost:8080/admin/coupling-test
即可测试分类三级联动功能
此文论述联动功能在SpringBoot项目中的实现,其要旨在监控前端选择框的change事件,并实时从后端获取数据填充分类选择框。