hap开发中的几个问题(遇到问题不慌不乱,想想问题的原因自然会解决)
1.查询时间匹配问题
原因:前端的Date类型格式与数据库(MySql)中的Date类型格式问题,所以在Controller中加如下代码解决。
//-。-这里这个方法解决时间查询时格式不统一的问题
@InitBinder
protected void init(HttpServletRequest request, ServletRequestDataBinder binder) {
//这里根据不同的情况选择需要的类型 :)
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
这里也给出一种查询方法中按照日期查询
mapper中查询条件这样写
<if test="startTime!=null and !''.equals(startTime) ">
AND DATE_FORMAT(a.START_TIME,'%y%m%d') =DATE_FORMAT(#{startTime},'%y%m%d')
</if>
2.查询过多时放入更多查询
类似于这种
第一步。
把查询条件放入两个(queryPanel)(query-form2)div中
<div id="queryPanel" class="pull-right" style="padding-bottom:5px;">
<div class="k-query-detail" id="query-form2">
<div class="rows">
<input id="evaluateTypeBox" data-bind="value:model.evaluateType" style="margin:1.2%;"
placeholder='<@spring.message "evaluation.evaluateType"/>'type="text">
</div>
<div class="rows">
<input id="evaluateDatePicker" data-bind="value:model.evaluatedDate" style="margin:1.2%; "
placeholder= '<@spring.message "studentevaluation.evaluateddate"/>' type="text">
</div>
<div class="rows">
<input id="appraiserLov" data-bind="value:model.evaluatedBy" style="margin:1.2%;"
placeholder= '<@spring.message "studentevaluation.appraiserName"/>' type="text">
</div>
<div class="rows">
<input id="appraiseeLov" data-bind="value:model.userId" style="margin:1.2%;"
placeholder='<@spring.message "studentevaluation.appraiseeName"/>'type="text">
</div>
</div>
</div>
第二步,内层div绑定数据
<script>kendo.bind($('#query-form2'), viewModel);</script>
第三步,把外层div放入更多查询的盒子
<script type="text/javascript">
$('#queryPanel').kendoQueryPanel({
/* queryFunction: function () {
viewModel.queryFunction();
},
resetFunction: function () {
viewModel.resetFunction();
} */
});
</script>
这样就把不好放的地方的查询放入了更多查询的盒子中。
3.lov联动问题
两个lov之间 后者依赖前者 这样的lov实现
第一步,写mapper配置lov。
第二步,前端调用
<div class="col-md-4">
<input id="studentBatchLov" data-bind="value:model.trainBatchCode" placeholder='<@spring.message "studentlearntrack.trainbatchcode"/>'type="text">
</div>
<div class="col-md-4">
<input id="routeHeadLov" data-bind="value:model.routeHeadId" placeholder='<@spring.message "studentlearntrack.routeHeadId"/>'type="text">
</div>
<div class="col-md-4">
<input id="groupLov" data-bind="value:model.groupId" placeholder='<@spring.message "evaluation.groupCode"/>'type="text">
</div>
第三步,初始化
// 初始化学生批次的LOV
$("#studentBatchLov")
.kendoLov($.extend(${lovProvider.getLov(base.contextPath, base.locale, "TRAIN_BATCH_LOV")}, {
select: function (e) {
if(typeof(viewModel.model.temp) != "undefined"){
if (viewModel.model.temp!= e.item.groupId) {
//这时说明groupLOV是被选过的则应该置空groupLov
$("#groupLov").data("kendoLov").text("");
$("#groupLov").data("kendoLov").value("");
viewModel.model.groupId= "";
viewModel.model.trainBatchCode= e.item.trainBatchCode;
}
}
},
change: function (e) {
if (e.sender._prev == null || e.sender._prev == '') {
viewModel.model.set("groupId", "");
viewModel.model.set("trainBatchCode", "");
$("#groupLov").data("kendoLov").text("");
}
}
}));
// 初始化学习路线的LOV
$("#routeHeadLov")
.kendoLov($.extend(${lovProvider.getLov(base.contextPath, base.locale, "ROUTE_HEAD_ID_LOV")}, {
//当选中时应当把groupLov置空
select: function (e) {
if(typeof(viewModel.model.temp) != "undefined"){
if (viewModel.model.temp!= e.item.groupId) {
//这时说明groupLOV是被选过的则应该置空groupLov
$("#groupLov").data("kendoLov").text("");
$("#groupLov").data("kendoLov").value("");
viewModel.model.groupId= "";
viewModel.model.routeHeadId = e.item.routeHeadId;
}
}
},
change: function (e) {
if (e.sender._prev == null || e.sender._prev == '') {
viewModel.model.set("groupId", "");
viewModel.model.set("routeHeadId", "");
$("#groupLov").data("kendoLov").text("");
}
}
}));
//初始化学习小组lov
$("#groupLov")
.kendoLov($.extend(${lovProvider.getLov(base.contextPath, base.locale, "LOV_GROUPS")}, {
query: function (e) {
//如果#studentBatchLov和routeHeadIdLov不为空
if(typeof(viewModel.model.routeHeadId) != "undefined" && viewModel.model.routeHeadId != ""&&typeof(viewModel.model.trainBatchCode) != "undefined" && viewModel.model.trainBatchCode != ""){
//把学习批次和学习路线传入
e.param['routeHeadId'] = viewModel.model.routeHeadId;
e.param['trainBatchCode'] = viewModel.model.trainBatchCode;
}
},
select: function (e) {
//temp为空则说明学习小组lov是没被选过的
viewModel.model.set("temp", e.item.groupId);
}
}))
4.gird中内容过多鼠标移动上出现全部内容
类似于这种
第一步,样式设置
<!--设置tooltip的样式-->
<style>
div[role=tooltip].k-tooltip{
padding: 2px;
background: #5c9acf;
}
.k-tooltip-content{
padding: 4px;
text-align: left;
background: #fff;
color: #666;
}
.k-callout {
border-bottom-color: #5c9acf;
}
</style>
第二步,设置数据显示样式
attributes:{style: "white-space:nowrap;text-overflow:ellipsis;"},
第三步,添加Tooltip
//add tooltip
$("#grid").kendoTooltip({
show: function(e){
if($.trim(this.content.text()) !=""){
$('[role="tooltip"]').css("visibility", "visible");
}
},
hide: function(){
$('[role="tooltip"]').css("visibility", "hidden");
},
filter: "td:nth-child(n+3)",
content: function(e){
var element = e.target[0];
if(element.offsetWidth < element.scrollWidth){
var text = $(e.target).text();
return '<div style="min-width:100px;max-width: 1000px;">' + text + '</div>';
}else{
$('[role="tooltip"]').css("visibility", "hidden");//解决鼠标一开始放在上面出现空模块
return "";
}
}
}).data("kendoTooltip");
此处参考https://blog.****.net/a1786223749/article/details/78330908
5.快码的使用
这里多说几句,hap框架中的快码时一个简单的表格就是value-meaning之间的储存方式,那吗快码的使用就方法多了一些。
第一种,前端绑定使用。
第一步,代码维护中配置
第二步,页面中配置
<!--学习方式的状态的快码-->
<script src="${base.contextPath}/common/code?learnStyleType=LT.LEARN_TYPE" type="text/javascript"></script>
第三步,使用
这时配置好了快码可以在learnStyleType中获取到相应的值。
- 前端容器
//这是放到了gird中如果
editor: function(container, options) {
$('<input name="'+ options.field + '"/>')
.appendTo(container)
.kendoComboBox({
dataSource: learnStyleType,
valuePrimitive: true,
dataTextField: "meaning",
dataValueField: "value"
});
},
2.也可以取值时直接显示意思
template: function (dataItem) {
var v = dataItem.learnStyle;
$.each(learnStyleType, function (i, n) {
if ((n.value || '').toLowerCase() == (v || '').toLowerCase()) {
v = n.meaning;
return false;
}
});
if(v==null){
return '';
}else{
return v;
}
}
第二种用于前端展示时也可以子啊sql中直接与数据库中的快码表连表查出meaning。
6.前端计算开始结束时间(分钟)
这里搞得比较复杂 因为业务要求。
开始结束时间只显示时分,计算出结果自动填充时长,时长不可编辑
第一步,确定gird中数据类型(主要是必输校验和时间类型显示)
startTime:{
validation: {required: true},
type:"date"
},
endTime:{
validation: {required: true},
type:"date"},
第二步,确定开始结束时间格式 进行计算 最后以时分形式显示(这里操作比较复杂没有找到好的解决方法 -.- )
{
field: "startTime",
title: '<@spring.message "studentlearntrack.starttime"/>',
width: 120,
format: "{0:HH:mm}",
editor: function(container, options) {
var end = options.model.endTime;
var d;
if(end){
d=end;
}
$('<input name="' + options.field + '"/>')
.appendTo(container)
.kendoTimePicker({
max:d,
culture: "zh-CN",
timeFormat: "HH:mm",
interval: 5 ,//15分钟
change:function(){
if(this.value()!=null){
d = this.value();
}else{
d= new Date(1900, 0, 1, 22, 0, 0);
}
}
});
},
template:function (dataItem) {
var time1 = dataItem.startTime;
var time2 = dataItem.endTime;
var temp = (time2.getHours()*60 + time2.getMinutes()) - (time1.getHours()*60 + time1.getMinutes());
dataItem.set("learnTime",temp);
var hour = time1.getHours();
var min = time1.getMinutes();
if(time1.getHours()<10){
hour = "0"+time1.getHours()+"";
}
if(time1.getMinutes()<10){
min = "0"+time1.getMinutes()+"";
}
return hour+""+":"+min;
}
},
{
field: "endTime",
title: '<@spring.message "studentlearntrack.endtime"/>',
width: 120,
format: "{0:HH:mm}",
editor: function(container, options) {
// options.model.endTime = options.model.startTime;
var start = options.model.startTime;
var d;
if(start){
d=start;
}
$('<input name="' + options.field + '"/>')
.appendTo(container)
.kendoTimePicker({
format:" HH:mm",
culture: "zh-CN",
interval: 5 ,//15分钟
min:d,
change:function(){
if(this.value()!=null){
d = this.value();
}else{
d= new Date();
}
}
});
},
//计算学习时长的方法并且返回当前时间的格式>。<
template:function (dataItem) {
var time1 = dataItem.startTime;
var time2 = dataItem.endTime;
var temp = (time2.getHours()*60 + time2.getMinutes()) - (time1.getHours()*60 + time1.getMinutes());
dataItem.set("learnTime",temp);
var hour = time2.getHours();
var min = time2.getMinutes();
//因为返回的格式并不是自己想要的类型所有设计一下返回格式-.-
if(time2.getHours()<10){
hour = "0"+time2.getHours()+"";
}
if(time2.getMinutes()<10){
min = "0"+time2.getMinutes()+"";
}
return hour+""+":"+min;
}
},
{
field: "learnTime",
title: '<@spring.message "studentlearntrack.learntime"/>',
width: 120,
//用来计算学习时长并且页面不可编辑-.-
editor: function (container, options) {
container.html(options.model.learnTime);
container.removeClass('k-edit-cell');
}
},
当然这里也可以在外面进行一步计算总学习时长,但是这里没有业务需求就没在做。
7.页面是否可编辑的函数
//col确定某一列
editable:function (col) {
//判断开始时间,更改是否可编辑
if (this.trackId !="" && (this.startTime.getDay() != newStartTime.getDay() ||this.startTime.getMonth()!= newStartTime.getMonth()||this.startTime.getFullYear()!= newStartTime.getFullYear())) {
// console.log(newStartTime.getDay());
// console.log(newStartTime.getFullYear());
// console.log(newStartTime.getMonth());
return false;
} else {
return true;
}
}
8.外部导入工具时(这里导入了Ueditor富文本编辑框)
第一步,导入文件,在前端导入如下放入文件方式
第二步,前端的应用这里可以直接去Ueditor官网去看 简单易上手
<script type="text/javascript" charset="utf-8">
//在导入外部插件时在webapp包下新建resources包放需要引入的插件
window.UEDITOR_HOME_URL = "/resources/js/ueditor/"; //UEDITOR_HOME_URL、config、all这三个顺序不能改变
</script>
<script type="text/javascript" charset="utf-8" src="/resources/js/ueditor/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="/resources/js/ueditor/ueditor.all.min.js"></script>
<!--建议手动加在语言,避免在ie下有时因为加载语言失败导致编辑器加载失败-->
<!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型,比如你在配置项目里配置的是英文,这里加载的文,那最后就是中文-->
<script type="text/javascript" charset="utf-8" src="/resources/js/ueditor/lang/zh-cn/zh-cn.js"></script>
<!-- 加载编辑器的容器 -->
<script id="editor" type="text/plain" name="content"></script>
<!-- 创建编辑器并设置属性 -->
<script type="text/javascript">
//建议使用工厂方法getEditor创建和引用编辑器实例,如果在某个闭包下引用该编辑器,直接调用UE.getEditor('editor')就能拿到相关的实例
//相见文档配置属于你自己的编译器
var ue = UE.getEditor('editor');
</script>
第三步,使用
1.首先加载页面时把 数据库中的内容设置到uetior中去
//加载方面
//通过trackId在数据库中找到comment
//把数据库中的comment内容在加载过程中放到Ueditor中去:)
function load(trackId){
$.ajax({
type: 'POST',
url: "${base.contextPath}/htr/student/learn/track/query",
data: {trackId: newTrackId},
success: function (data) {
$.each(data.rows, function (i, item) {
if (trackId == item.trackId && trackId != 0) {//form填充
viewModel.model.set("comment", item.comment);
//设置内容到UEtitorz中
ue.ready(function () {
ue.setContent(viewModel.model.comment);
});
}
});
}
});
}
2.把uetior中的内容提交(这里处理比较笨重)
{
field: "comment",
title: '<@spring.message "studentlearntrack.comment"/>',
width: 120,
template:function (dataItem) {
if(ue.hasContents()){
dataItem.comment = ue.getContent();
}else{
dataItem.comment = '';
}
dataItem.dirty=true;
return dataItem.comment;
},
重写了保存方法
saveFunction:function () {
$('#grid').data('kendoGrid').saveChanges().done(function(e){
//需要保存成功后再次保存才能提交到数据库
$('#grid').data('kendoGrid').saveChanges()
$('#grid').data('kendoGrid').dataSource.page(1); //刷新数据
});
},
9.页面传值问题
第一步,设置一个超链接(这里格式一定要正确这里深坑)
template: function (dataItem) {
var trainBatchCode = dataItem.trainBatchCode;
var rid = dataItem.routeHeadId;
var temp = '<@spring.message "studentgroupassign.learmTrack"/>';
return '<a href="javascript:void(0)" onclick="viewLearnTrack(\'' + trainBatchCode + '\',\'' + rid + '\')">' + temp + '</a>';
}
第二步,写一个上面的方法把值通过get方法提交到下一个页面
//确定下一个页面的初始查询条件
viewLearnTrack = function (trainBatchCode, rid) {
var win = $('#newWin').kendoWindow({
iframe: true,
draggable: false,
content: '${base.contextPath}/learnTrack/student_learn_track.html?trainBatchCode=' + trainBatchCode + '&routeHeadId=' + rid
}).data('kendoWindow');
win.title('<@spring.message "studentlearntrack.strudentLearnTrackContent"/>');
win.maximize().open();
};
第三步,下一个页面接收值
//使用FreeMarker获取订单头地址栏传来的trainBatchCode和routeHeadId
var newTrainBatchCode = '${RequestParameters.trainBatchCode!0}';
var newRouteHeadId = '${RequestParameters.routeHeadId!0}';
10. 重写删除方法
function deleteData() {//自定义批量删除函数
var checked;
checked = grid.selectedDataItems();//获取选中的行
if(grid.selectedDataItems().length){
// var temp = new Date()
// if(viewModel.startTime.getDay()==temp.getDay()){
//
// }else{
//
// }
kendo.ui.showConfirmDialog({
title:$l('hap.tip.info'),
message: $l('hap.tip.delete_confirm'),
}).done(function (event) {
if (event.button == 'OK') {
$.ajax({
type : "POST",
url : "${base.contextPath}/htr/student/learn/track/remove",
data : kendo.stringify(checked),//数据转json
dataType:"json",
contentType:"application/json",
success: function(e) {
if(e.message){
kendo.ui.showInfoDialog({
message:'<@spring.message "hap.tip.dateerror"/>'
})
}else{
$.each(checked,function(i,v){
grid.dataSource.remove(v)
});
kendo.ui.showInfoDialog({
message:'<@spring.message "hap.tip.success"/>'
})
}
}
});
}
})
}else{
kendo.ui.showInfoDialog({
message:$l('hap.tip.selectrows')
})
}
};
11.后台直接向前端返回报错信息
public ResponseData saveLearnTrack(IRequest request, List<StudentLearnTrack> dto){
//用于返回的数据类型
ResponseData responseData = new ResponseData();
Criteria criteria = new Criteria();
criteria.update(new String[]{"trainBatchCode", "routeHeadId", "userId", "contentId", "startTime", "endTime", "learnTime", "learnStyle", "comment"});
criteria.updateExtensionAttribute();
Iterator var4 = dto.iterator();
while(var4.hasNext()) {
StudentLearnTrack studentLearnTrack = (StudentLearnTrack)var4.next();
String var6 = studentLearnTrack.get__status();
byte var7 = -1;
switch(var6.hashCode()) {
case -1335458389:
if (var6.equals("delete")) {
var7 = 2;
}
break;
case -838846263:
if (var6.equals("update")) {
var7 = 1;
}
break;
case 96417:
if (var6.equals("add")) {
var7 = 0;
}
}
switch(var7) {
case 0:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//开始日期
String ds2 = sdf.format(studentLearnTrack.getStartTime());
//结束日期
String ds3 = sdf.format(studentLearnTrack.getEndTime());
//开始日期雨结束日期应保持同一天
String ds4 = ds2.split(" ")[0]+" "+ ds3.split(" ")[1];
try {
Date date = sdf.parse(ds4);
studentLearnTrack.setEndTime(date);
} catch (ParseException e) {
e.printStackTrace();
}
//如果开始结束时间在某个时间段内则开始结束时间非法
List<StudentLearnTrack> temp = selectStudentTrackByTime(request,studentLearnTrack);
//新建时应该保证一条不符合规则的内容都没有
if (temp ==null || temp.size()==0){
((IStudentLearnTrackService)this.self()).insertSelective(request, studentLearnTrack);
}else{
// throw new RuntimeException("开始结束时间非法");
//请求失败 并返回报错信息
responseData.setSuccess(false);
responseData.setMessage("开始结束时间非法");
return responseData;
}
break;
case 1:
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
//开始日期
String ds5 = sdf1.format(studentLearnTrack.getStartTime());
//当前天数
String ds6 = sdf1.format(new Date());
if(ds6.equals(ds5)){
List<StudentLearnTrack> temp1 = selectStudentTrackByTime(request,studentLearnTrack);
//当包保存时至少有一条是符合要求 因为与自身冲突
if (temp1.size()<= 1){
((IStudentLearnTrackService)this.self()).updateByPrimaryKeyOptions(request, studentLearnTrack, (Criteria)null);
}else {
//当多余一条时说明不仅与自身冲突 还有其他的数据 所以抛出异常
responseData.setSuccess(false);
responseData.setMessage("开始结束时间非法");
return responseData;
}
}else {
responseData.setSuccess(false);
responseData.setMessage("只能修改当天记录");
return responseData;
}
break;
case 2:
((IStudentLearnTrackService)this.self()).deleteByPrimaryKey(studentLearnTrack);
}
}
return responseData;
这是我第一次hap开发中遇到的几个问题以及问题的解决方法,虽然问题不多但是自己解决浪费不少时间希望以后可以顺利解决。