最近项目中要使用FreeMarker,DWZ等前端技术,所以会搜集一些相关文章,都是来自网上,供自己和大家查阅,以下是DWZ篇,不定时更新:
由于DWZ文档比较多,所以不再介绍如何使用,详情可参考DWZ-JUI,上面有文档和视频。此处主要介绍DWZ使用过程中的常见问题和解决方法,多数搜集于网上,在此留个备份以供大家参考。
1、DWZ获取Dom节点应注意的问题
DWZ 核心就是通过Ajax 获取Html 片段,然后append到页面当中,这样就会出现一个问题,你在一个Html 片段中 为一个节点添加的ID是唯一的,但是在整个页面中不一定是唯一的,比如你在一个dialog Html片段中一个Id是唯一的,但是你多次打开这个Dialog 并同时呈现在前台 ,那么这个ID就不是唯一的了,$("#id") 根据ID获取时就会出现 ID 冲突,获取不到真正想要的对象。
常规的解决方法:
$("#id",$.pdialog.getCurrent()) 根据id 获取当前dialog的dom节点 $("#id",navTab.getCurrent()) 根据id 获取当前navTab的dom节点其实你根据 其他的属性获取节点时 也应该注意此问题。 你的属性设定的范围是整个前端页面,而不是一个HTML片段
2、dwz.frag.xml 初始化问题
有些人把demo 下载下来不能运行,可能是浏览器不支持javascript加载本地dwz.frag.xml文件(IE下就会报错),改用火狐就可以了
$(function(){ DWZ.init("dwz.frag.xml", { loginUrl:"login_dialog.html", loginTitle:"登录", // 弹出登录对话框 // loginUrl:"login.html", // 跳到登录页面 statusCode:{ok:200, error:300, timeout:301}, //【可选】 pageInfo:{pageNum:"pageNum", numPerPage:"numPerPage", orderField:"orderField", orderDirection:"orderDirection"}, //【可选】 debug:false, // 调试模式 【true|false】 callback:function(){ initEnv(); $("#themeList").theme({themeBase:"themes"}); // themeBase 相对于index页面的主题base路径 } }); });首先 DWZ的使用和你开发使用的语言是没有关系的。在初始话函数中第一个参数就是指定 dwz.frag.xml地址。你可以使用绝对路径或者相对路径指向你的 dwz.frag.xml 在服务器上的地址。具体存放的位置你可以自己选择,一般就直接放在原始的js文件夹就可以了。
3、整合第三方JQuery插件
jQuery插件一般是$(document).ready()中初始化。
$(document).ready(function(){ // 文档就绪,初始化jQuery插件| }); // 或者或缩写形式 $(function(){ // 文档就绪,初始化jQuery插件 });因为DWZ RIA是富客户端思路,第一次打开时加载界面到浏览器端,之后和服务器的交互是存数据交互,不占用界面相关的网络流量。
DWZ初始化ajax加载的页面中的第三方jQuery组件:
一般插件初始化在dwz.ui.js 中的initUI 里面处理,initUI()方法会被DWZ框架封装的$.fn.loadUrl()自动调用。如果是jQuery原生load方法需要手动调用$.fn.initUI()插件。注意在initUI()方法中初始化是要注意作用域的,里面有一个$p代表当前ajax加载的容器,只要初始化当前容器新加载的内容就可以了
if ($.fn.ajaxTodo) $("a[target=ajaxTodo]", $p).ajaxTodo(); if ($.fn.dwzExport) $("a[target=dwzExport]", $p).dwzExport();如果一些特殊的ajax交互,自己写回调函数处理 。
4、跨域请求 iframeNavTab
如果想navTab访问其他的网址,可以使用 iframe navTab,使用方法如下:
<a href="http://www.baidu.com" target="navTab" rel="external"external="true">iframe navTab页面</a>
external="true" 会使用 iframe ,有些初级用户会忘记加target="navTab",只有加上这个属性才会使用navTab。
详细看dwz-ui.js
5、左侧菜单初始化是关闭状态
有些时候我们想使左侧菜单初始化时是关闭状态的,低版本的DWZ在设计时不是很灵活,2.0版本的貌似已经有所改善,低版本的可以使用以下方式来解决这个问题:
在 dwz-ui.js 文件下
$('div.accordion', $p).each(function(){ var $this = $(this); $this.accordion({fillSpace:$this.attr("fillSpace"),alwaysOpen:true,active:0}); });
修改为
$('div.accordion', $p).each(function(){ var $this = $(this); $this.accordion({fillSpace:$this.attr("fillSpace"),alwaysOpen:false,active:-1}); });
如果想让左侧栏默认是关闭状态,初始化时是全屏状态,只需如下处理:
$(function(){ DWZ.init("dwz.frag.xml", { loginUrl:"login_dialog.html", loginTitle:"登录", // 弹出登录对话框 // loginUrl:"login.html", // 跳到登录页面 statusCode:{ok:200, error:300, timeout:301}, //【可选】 pageInfo:{pageNum:"pageNum", numPerPage:"numPerPage", orderField:"orderField", orderDirection:"orderDirection"}, //【可选】 debug:false, // 调试模式 【true|false】 callback:function(){ initEnv(); $("#themeList").theme({themeBase:"themes"}); //加入以下代码!!!!!!!!!!!!!!!!!!!!! $("#sidebar .toggleCollapse div").trigger("click"); } }); });7、Ajax请求session超时处理
ajax请求session超时处理流程如下:
1)SessionValidateFilter统一验证session是否超时
2)SessionValidateFilter中判断请求是否为ajax请求
3)ajax请求session超时返回一个json {"statusCode":"301", "message":"Session Timeout! Please re-sign in!"}
4)dwz js框架根据statusCode==301,处理是跳转到登陆页面或者弹出登录dialog
java服务器端处理:
SessionValidateFilter中修改:
if ("XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With")) || request.getParameter("ajax") != null) { PrintWriter out = response.getWriter(); out.println({"statusCode":"301", "message":"Session Timeout! Please re-sign in!"}); } else { response.sendRedirect(response.encodeRedirectURL(this.loginUrl + java.net.URLEncoder.encode(backToUrl, "UTF-8"))); }js客户端处理:
<script type="text/javascript"> $(function(){ DWZ.init("dwz.frag.xml", { // loginUrl:"loginsub.html", loginTitle:"登录", // 弹出登录对话框 loginUrl:"login.html", // 跳到登录页面 statusCode:{ok:200, error:300, timeout:301}, //【可选】 pageInfo:{pageNum:"pageNum", numPerPage:"numPerPage", orderField:"orderField", orderDirection:"orderDirection"}, //【可选】 debug:false, // 调试模式 【true|false】 callback:function(){ initEnv(); $("#themeList").theme({themeBase:"themes"}); } }); }); </script>ajax load页面碎片处理:
session超时弹出登录dialog注意事项:
1、用一个带屏蔽层的dialog覆盖的整个浏览器.这时浏览器窗口内容不能变,只是上面加了一个登录框和一个背景层。
2、当用户输入username and password登录成功后,去掉登录框和背景层.这时用户可以继续操作.
3、登录失败alert出错信息,浏览器窗口内容还是不变.
参考dwz.core.js代码片段:
loadUrl: function(url,data,callback){ var $this = $(this); $.ajax({ type: 'POST', url: url, cache: false, data: data, success: function(response){ var json = DWZ.jsonEval(response); if (json.statusCode==DWZ.statusCode.timeout){ alertMsg.error(DWZ.msg("sessionTimout"), {okCall:function(){ DWZ.loadLogin(); }}); } if (json.statusCode==DWZ.statusCode.error){ if (json.message) alertMsg.error(json.message); } else { $this.html(response).initUI(); if ($.isFunction(callback)) callback(response); } }, error: DWZ.ajaxError }); }ajax post 表单数据处理: 当客户端ajax提交表单超时原理同ajax load
参考dwz.core.js代码片段:
ajaxDone:function (json){ if(json.statusCode == DWZ.statusCode.error) { if(json.message && alertMsg) alertMsg.error(json.message); } else if (json.statusCode == DWZ.statusCode.timeout) { if(json.message && alertMsg) alertMsg.error(json.message, {okCall:DWZ.loadLogin}); else DWZ.loadLogin(); } else { if(json.message && alertMsg) alertMsg.correct(json.message); }; }注意事项:
{"statusCode":"301", "message":"Session Timeout! Please re-sign in!"}8、表单提交重定向问题
表单提交navTab重定向问题:
dwz 中提供了简单的navTabAjaxDone 回调函数,在form中可以直接采用:
Form标签上增加”onsubmit=return validateCallback(this, navTabAjaxDone)",
表单返回的json格式为:
{ "statusCode":"200", "message":"操作成功", "navTabId":"", "callbackType":"", "forwardUrl":"" }
如果是想提交表单后,关闭当前的navTab 并刷新某个navTab,比如你在一个navTab中修改了用户,修改成功后想刷新一下用户的列表,navTab页面可以写成下面样子:
{ "statusCode":"200", "message":"操作成功", "navTabId":"listUser",//用户列表的navTba rel id "callbackType":"closeCurrent",//关闭当前页面 "forwardUrl":"" }如果是想提交表单后转发到另一个页面可以这样写:
{ "statusCode":"200", "message":"操作成功", "navTabId":"", "callbackType":"forward",//转发到其他页面 "forwardUrl":"newPage.do"//转发页面的地址 }这些问题在文档“服务器端响应”中都可以找到,使用前最好先看看文档。 9、页面定义函数应注意的问题
在网上看到有人提到dwz的页面定义函数的被覆盖的问题,dwz 所有的页面都是通过ajax访问,然后append到页面当中,当你在html片段中加入脚本语言时,实际上是用的同一个Window,当函数有重复的名时,并且这两个页面又同时通过navTab或者dialog展示在页面当中,那么你的函数就会被覆盖了。
所以写插入脚本的时候要注意以下问题:
1、 如果是通用的函数,那么最好写成js文件加载到index页面当中。
2、 如果是定义在html片段的函数,那么自己应注意最好名字不要有重复的,或者名字重复但保证不会同时展现出来,如通过模式窗口限制。
10、可以伸缩的查询面板(searchBar)
最近有这样的需求,一个页面查询条件特别多,一次全部展示出来的话就占用大量的空间,所以分成了两类,简单搜索和高级搜索,当点击高级搜索的时候就会全部显示。
这样就存在一个问题,页面(navTab,dialog)上下pageHeader panelBar 高度是由 layoutH值决定的,如果上面的面板变高,就会把下面的分页标签撑出,
解决的方法就是当改变searchpanel的高度时,获取前后的高度差,修改当前页面元素的layoutH值重新layout一下:
$("document").ready(function(){ $("#gjjs").click(function(){ $this = $(this); var yh = $("#workplan_search").height(); if($this.text()=='高级检索'){ $this.text('简单检索') }else{ $this.text('高级检索') } $("#workplan_search .complex").toggle(); var xh = $("#workplan_search").height(); var $panel=$this.parents('.unitBox:first').find("[layoutH]").each(function(){ $(this).attr("layoutH",parseInt($(this).attr("layoutH"))+(xh-yh)); $(this).layoutH(); }); return false; }); });