说明:前端使用layui,后端spring mvc.
页面是这样的:
代码:
<script id="secRoleFunctionTpl" type="text/html">
<div style="padding-top: 30px;padding-left:20px; margin-right: 50px">
<form class="layui-form layui-form-pane" id="secRoleFunctionForm">
<div class="layui-form-item">
{{# layui.each(d.list, function(index, item){ }}
<div class="layui-form-item">
<label class="layui-form-label formLabel-100">一级菜单</label>
<div class="layui-input-block">
{{# if(item.isChecked){ }}
<input type="checkbox" name="fristFunc" title="{{item.fristFunc.funcName}}"
data-value="{{item.fristFunc.fid}}" lay-filter="fristFuncCheckbox"
checked>
{{# } }}
{{# if(!item.isChecked){ }}
<input type="checkbox" name="fristFunc" title="{{item.fristFunc.funcName}}"
data-value="{{item.fristFunc.fid}}" lay-filter="fristFuncCheckbox"
>
{{# } }}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label formLabel-100">二级菜单</label>
<div class="layui-input-block">
{{# layui.each(item.secondFuncList, function(indexChild, itemChild){ }}
{{# if(item.fristFunc.fid==itemChild.parentFid){ }}
{{# if(itemChild.isChecked){ }}
<input type="checkbox" name="secondFuncList" title="{{itemChild.funcName}}"
data-value="{{itemChild.fid}}" lay-filter="secondFuncCheckbox"
checked>
{{# } }}
{{# if(!itemChild.isChecked){ }}
<input type="checkbox" name="secondFuncList" title="{{itemChild.funcName}}"
data-value="{{itemChild.fid}}" lay-filter="secondFuncCheckbox"
>
{{# } }}
{{# } }}
{{# }); }}
</div>
</div>
{{# }); }}
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="secRoleFunctionButton">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</script>
如上所示,每个checkbox都有一个fid。因为菜单数量是动态的,所以使用List<SecRoleFuncVO>的方式来做数据保存。结构如下:
public class SecRoleFuncVO implements Serializable {
private SecFunction fristFunc;
private List<SecFunction> secondFuncList;
private Integer roid;
public Integer getRoid() {
return roid;
}
public void setRoid(Integer roid) {
this.roid = roid;
}
public SecFunction getFristFunc() {
return fristFunc;
}
public void setFristFunc(SecFunction fristFunc) {
this.fristFunc = fristFunc;
}
public List<SecFunction> getSecondFuncList() {
return secondFuncList;
}
public void setSecondFuncList(List<SecFunction> secondFuncList) {
this.secondFuncList = secondFuncList;
}
}
roid是固定的,并不用管。至于SecFunction类的结构,它里面差不多只有一个int型的fid字段。换句话说,其实整个页面就是要取这些checkbox的fid值就好了。
但是有个问题,控制器的参数不接受类集合,所以我又建了一个类来保存上面的List<SecRoleFuncVO>:
public class ParameterList implements Serializable {
private List<SecRoleFuncVO> secRoleFuncVOList;
public List<SecRoleFuncVO> getSecRoleFuncVOList() {
return secRoleFuncVOList;
}
public void setSecRoleFuncVOList(List<SecRoleFuncVO> secRoleFuncVOList) {
this.secRoleFuncVOList = secRoleFuncVOList;
}
}
然后控制器的代码:
/**
* 保存或修改已分配的菜单
*
* @param paramList
* @return
*/
@RequestMapping("/saveOrUpSecRoleFunction")
@ResponseBody
public Json saveOrUpSecRoleFunction(ParameterList paramList) {
Json json = new Json();
try {
secService.saveOrUpSecRoleFunction(paramList.getSecRoleFuncVOList());
json.setSuccess(true);
} catch (Exception e) {
e.printStackTrace();
json.setMsg(e.getMessage());
}
return json;
}
接着是把页面的值取过来。本来如果只有一条数据,那么按说控制器参数的类会自动识别页面上的控件名,但是这个页面是动态的,并且有一级,二级两层,数据会有N条。所以我只能选择在js里写:
//分配菜单事件
function secRoleFunction(roid) {
var result = $.loadData('/sec/querySecRoleFunctionByRoid?roid=' + roid);
if (!result.success) {
layer.msg(result.msg);
} else {
openSecRoleFunction('分配菜单', result.obj, roid);
}
}
// 提交菜单
function openSecRoleFunction(title, Data, roid) {
var tplHtml;
var data = {'list': Data};
layui.laytpl(secRoleFunctionTpl.innerHTML).render(data, function (html) {
tplHtml = html;
});
layerIndex = layer.open({
type: 1,
title: title,
area: ['400', '400'],
success: function () {
form = layui.form;
form.render();
$('#secRoleFunctionForm')[0].reset();
form.on('submit(secRoleFunctionButton)', function (data) {
var object = data.field;
var SecRoleFuncVOList = new Array();//实体集合
$('input:checkbox[name="fristFunc"]:checked').each(function (indexFirst, itemFirst) {//循环一级菜单
var SecRoleFuncVO = {};//实体
//角色编号
SecRoleFuncVO['roid'] = roid;
//一级菜单
var fristFunc = {fid: $(itemFirst).data('value')};
SecRoleFuncVO['fristFunc'] = fristFunc;
//二级菜单
var secondItem = $(itemFirst).parent().parent().next().children('div').children('input:checkbox[name="secondFuncList"]:checked');
var secondFuncList = new Array();//二级菜单集合
secondItem.each(function (indexSecond, itemSecond) {
var secondFunc = {fid: $(itemSecond).data('value')};
secondFuncList.push(secondFunc);
});
SecRoleFuncVO['secondFuncList'] = secondFuncList;
SecRoleFuncVOList.push(SecRoleFuncVO);
});
var paramList = {};//实体
paramList['secRoleFuncVOList'] = SecRoleFuncVOList;
object = paramList;
console.table(object);
layer.msg('提交中,请稍候', {icon: 16, time: false, shade: 0.8});
$.post('/sec/saveOrUpSecRoleFunction', object ,
function (data) {
if (data.success) {
layer.close(layerIndex);
layer.msg("操作成功!");
} else {
layer.msg(data.msg);
}
}
);
return false;
}
);
}
,
shadeClose: true,
area:
['1000px', '600px'],
content:
tplHtml
})
;
}
调试时结果很正常(请参照SecRoleFuncVO类):
但是,根本不进控制器,并且报了这个错误:
如果我将js中的
var paramList = {};//实体
paramList['secRoleFuncVOList'] = SecRoleFuncVOList;
object = paramList;
改成
object =SecRoleFuncVOList;
那么能进控制器,但结果是这样:
也就是说,不管我怎么写,值就是进不了控制器,请问这个要怎么解决呢?
或者说,各位大神有更好的方法让页面的值传进后台吗?(比如不通过js)
这个问题我之前也碰到过,你试一下在参数对象上面加一个 @RequestBody 如下图:
