(原文地址:http://blog.csdn.net/jiweigang1/article/details/7519781)
前一阵子有朋友问道 navTabPageBreak 查询参数无法传递的问题,只有一张图片,我很难找到具体原因,在这里我把整个流程分析一下,这样自己找找问题所在,
也希望能给其他的朋友带来帮助。
我以表格控件的 分页显示数量为例。dwz-ria-1.4.3
先说一下流程
1 分页的Combox控件的 onchange事件 触发 navTabPageBreak
2 navTabPageBreak 实质上是调用的 dwzPageBreak 方法
这里我就重点说明一下dwzPageBreak方法
[html] view plaincopy
- /**
- * 处理navTab中的分页和排序
- * @param args {pageNum:"n", numPerPage:"n", orderField:"xxx", orderDirection:""}
- * @param rel: 可选 用于局部刷新div id号
- */
- function navTabPageBreak(args, rel){
- //实质上调用的 dwzPageBreak 方法,dwzPageBreak 是对navTab和dialog通用一个方法
- dwzPageBreak({targetType:"navTab", rel:rel, data:args});
- }
- /**
- * 处理navTab中的分页和排序
- * targetType: navTab 或 dialog
- * rel: 可选 用于局部刷新div id号
- * data: pagerForm参数 {pageNum:"n", numPerPage:"n", orderField:"xxx", orderDirection:""}
- * callback: 加载完成回调函数
- */
- //这个方法是重点
- function dwzPageBreak(options){
- //这里设置一些默认是属性
- var op = $.extend({ targetType:"navTab", rel:"", data:{pageNum:"", numPerPage:"", orderField:"", orderDirection:""}, callback:null}, options);
- //获取默认的父容器,一般就是当前的dialog和当的navTab
- var $parent = op.targetType == "dialog" ? $.pdialog.getCurrent() : navTab.getCurrentPanel();
- //这里是局部的刷新, 流程就是通过Ajax请求获取到新的html片段,替换掉 指定的id (op.rel)节点,然后从新格式化布局。
- if (op.rel) {
- var $box = $parent.find("#" + op.rel);
- //获取当前页面的查询form 下面会重点讲解
- var form = _getPagerForm($box, op.data);
- if (form) {
- //获取新的html片段,替换掉原始的。
- $box.ajaxUrl({ //获取查询表单里参数,所以刷新页面时表表单数据是一并发过去的
- type:"POST", url:$(form).attr("action"), data: $(form).serializeArray(), callback:function(){
- //重新格式化布局
- $box.find("[layoutH]").layoutH();
- }
- });
- }
- //刷新整个 navTab、或者 dialog
- } else {
- //获取当前页面的查询form 下面会重点讲解
- var form = _getPagerForm($parent, op.data);
- //获取查询表单里参数,所以刷新页面时表表单数据是一并发过去的
- var params = $(form).serializeArray();
- //通过各个reload方法可以刷新
- if (op.targetType == "dialog") {
- if (form) $.pdialog.reload($(form).attr("action"), {data: params, callback: op.callback});
- }else{
- if (form) navTab.reload($(form).attr("action"), {data: params, callback: op.callback});
- }
- }
- }
- /**
- *
- * @param {Object} args {pageNum:"",numPerPage:"",orderField:"",orderDirection:""}
- * @param String formId 分页表单选择器,非必填项默认值是 "pagerForm"
- */
- //dwzPageBreak 方法调用这个方法
- function _getPagerForm($parent, args) {
- //获取当前页面下查询Form节点
- //#pagerForm Id 名字很重要 如果传递不了参数,可以检查一下 ID 名称
- var form = $("#pagerForm", $parent).get(0);
- if (form) {
- //在这里会把你传递的参数附上。
- if (args["pageNum"]) form[DWZ.pageInfo.pageNum].value = args["pageNum"];
- //<select class="" onchange="navTabPageBreak({numPerPage:this.value})" name="numPerPage">
- //在这里附上值,从而达到你切换数量时刷新页面的效果
- if (args["numPerPage"]) form[DWZ.pageInfo.numPerPage].value = args["numPerPage"];
- if (args["orderField"]) form[DWZ.pageInfo.orderField].value = args["orderField"];
- if (args["orderDirection"] && form[DWZ.pageInfo.orderDirection]) form[DWZ.pageInfo.orderDirection].value = args["orderDirection"];
- }
- return form;
- }
WZ下ajax后台交互后的分页刷新
2013-5-1阅读1747 评论1
之前做的几个项目,用上了DWZ这个UI框架作为管理后台的界面,觉得还是不错的。个人觉得有点遗憾的是这个框架的整体感觉不够企业化,缺少稳重的感觉。
在开发过程中,碰到了一些问题,这里跟大家分享一下。
DWZ版本:
DWZ RIA 1.3 Final
说明:因为之前做过一些自定义,是直接将 dwz.min.js 改成 dwz.newgxu.js ,这样做对整个框架修改过大,造成以后更新与维护的各种不便。所以,现在作的修改是以覆盖的方式进行。
问题描述:
在一些分页的NAV中,进行 ajaxToDo 或者 弹出Dialog的validateCallback 后,服务器返回的json为:
{"statusCode":"200", "message":"权限删除成功", "navTabId":"permission_list","rel":"", "callbackType":"","forwardUrl":"permission/list"}
这里,会将整个NAV刷新,但我们想要的只是刷新当前页。
下面就这个问题作一些修正。
首先说一下DWZ与后台交与的形式:
1. 通过 <a target="ajaxToDo" href="http://m.cnblogs.com/164131/"></a>
{
DWZ.ajaxDone(json);
if (json[DWZ.keys.statusCode] == DWZ.statusCode.ok)
{
if (json.navTabId)
{ //把指定navTab页面标记为需要“重新载入”。注意navTabId不能是当前navTab页面的
navTab.reloadFlag(json.navTabId);
//就像上面的一个文章中所说的,一个常常希望的功能就是,新打开的页面编辑完成后,
//列表页面也会刷新,但是这里reloadFlag方式设置重新载入会跳回初始界面,不会刷新
//当前页列表.
//下面的else分支中,会刷新当前分页的列表。但是在这里调用navTabPageBreak也不能
//实现,因为navTabPageBreak的代码里还是会调用getCurrentPanel。
}
else
{ //重新载入当前navTab页面
var $pagerForm = $("#pagerForm", navTab.getCurrentPanel());
var args = $pagerForm.size()>0 ? $pagerForm.serializeArray() : {}
navTabPageBreak(args, json.rel);
//返回的json中如果木有指定navTabId,就会走上面这个esle分支,navTabPageBreak中,重新获取
//当前页面上的form然后提交,能够保证刷新后停留在当前页面上。
}
if ("closeCurrent" == json.callbackType)
{
setTimeout(function(){navTab.closeCurrentTab(json.navTabId);}, 100);
}
else if ("forward" == json.callbackType)
{
navTab.reload(json.forwardUrl);
}
else if ("forwardConfirm" == json.callbackType)
{
alertMsg.confirm(json.confirmMsg || DWZ.msg("forwardConfirmMsg"),
{
okCall: function()
{
navTab.reload(json.forwardUrl);
},
cancelCall: function()
{
navTab.closeCurrentTab(json.navTabId);
}
});
}
else
{
navTab.getCurrentPanel().find(":input[initValue]").each(function()
{
var initVal = $(this).attr("initValue");
$(this).val(initVal);
});
}
}
}
//至少从这个函数里,看不出来应该怎样的简便的实现记住查询条件的刷新列表页。
//上面文章里的方法又太麻烦。一个简单的近似方法是:
这里点击这个标签会向后台post请求,地址就是 href 的值,ajax的回调函数默认是
navTabAjaxDone
2. 通过 target="dialog"
如增加一个新用户,以dialog的方式弹出输入界面,这样写:
<a class="BUTTON" href="user/add" width="300" height="250" target="dialog"
rel="rank_create" fresh="false">添加用户</a>
弹出内容:
<form name="form1" method="post" action="user/add" onsubmit=
"return validateCallback(this, dialogAjaxDone);"></form>
提交这个表单后,回调函数为 dialogAjaxDone。
再说说DWZ分页的实现:
<div class="pageHeader RIGHT">
<form id="pagerForm" name="permission_list_pageForm" style="display:none;"
action="permission/list" method="get" onsubmit="returnnavTabSearch(this);">
<input type="hidden" name="page" value="${model.page}"/>
</form>
</div>
<div class="pageContent">
<table class="table" width="100%" border="1" layoutH="85" align="center"
cellspacing="0" bordercolor="#999999" style="border-collapse:collapse">
<thead>
<tr>
<th width="3%">ID</th>
<th width="6%">应用名称</th>
<th width="10%">名称</th>
<th width="8%">模块名</th>
<th width="8%">方法名</th>
<th width="30%">说明</th>
<th width="8%">添加人</th>
<th width="15%">添加时间</th>
<th width="10%">操作</th>
</tr>
</thead>
</table>
<div class="panelBar">
<div class="pages">
<span>共${model.totalCount}条</span>
</div>
<div class="pagination" targetType="navTab" totalCount=
"${model.totalCount}" numPerPage="${model.pageSize}"
pageNumShown="16" currentPage="${model.page}"></div>
</div>
</div>
说明:
可以按照上面的div分层格式写,id="pagerForm" 这个一定需要。
好了,现在开始实现刷新当前分页。先作一些准备工作:
给id="pagerForm" 增加一个唯一的名称,格式:当前{navTabId}_pageForm。
在这个Form中的 name="page" 给一个值,这个值就是当前的页码,这样方便分页刷新。
然后将下面两个方法加入到 总的页面中,一般是 加载dwz框架的页面,如index.html:
/**
* 弹出窗口编辑提交后,异步处理函数,在这里会刷新当前的分页table的值
*
* 思路:
手动提交 pagerForm 这个表单
*
* 确保 id=pagerForm 的表单存在,参考:
* ====================================================================================
* <form id="pagerForm" style="display:none;"
* action="permission/list" method="get" οnsubmit="return navTabSearch(this);">
* <input type="hidden" name="page" value="1" /><!--【必须】value=1可以写死-->
* </form>
* ------------------------------------------------------------------------------------
* 修改action为相应的地址即可
* ====================================================================================
*
* 3.修改弹出的dialog回调函数的声明:
* <form name="form1" method="post" action="permission/add"
* οnsubmit="return validateCallback(this, dialogAjaxDone_fresh);">
*
* 将原来的 dialogAjaxDone 改成下面的函数名即可。
*
* @param {Object} json
*/
function dialogAjaxDone_fresh(json){
DWZ.ajaxDone(json);
if(json.statusCode==DWZ.statusCode.ok){
$("form[name="+json.navTabId+"_pageForm]").submit();
$.pdialog.closeCurrent();
}
}
/**
* 重写 navTabAjaxDone方法
*
* @param {Object} json
*/
function navTabAjaxDone(json){
DWZ.ajaxDone(json);
if(json.statusCode==DWZ.statusCode.ok){
if(json.navTabId){
//先判断当前的nav是否有 pagerForm,
//有,就刷新这个nav 中的分页控件
var $pageForm = $("form[name="+json.navTabId+"_pageForm]");
if($pageForm){
console.log("刷新分页");
$pageForm.submit();
}else{
console.log("刷新本Nav");
navTab.reloadFlag(json.navTabId);
}
}else{
navTabPageBreak({},json.rel);
}
if("closeCurrent"==json.callbackType){
setTimeout(function(){navTab.closeCurrentTab();},100);
}else if("forward"==json.callbackType){
navTab.reload(json.forwardUrl);
}
}
}
然后修改dialog中的回调函数 为我们的新加的函数:
<form name="form1" method="post" action="user/add" onsubmit="return
validateCallback(this, dialogAjaxDone_fresh);"></form>
对于 ajaxToDo 形式的交互,不需要修改。
至此,完成。
--------------------------------------------------------------------------------------------------------------------
navTabAjaxDone函数的简要注释
/**
* navTabAjaxDone是DWZ框架中预定义的表单提交回调函数.
* 服务器转回navTabId可以把那个navTab标记为reloadFlag=1, 下次切换到那个navTab时会重新载入内容.
* callbackType如果是closeCurrent就会关闭当前tab
* 只有callbackType="forward"时需要forwardUrl值
* navTabAjaxDone这个回调函数基本可以通用了,如果还有特殊需要也可以自定义回调函数.
* 如果表单提交只提示操作是否成功, 就可以不指定回调函数. 框架会默认调用DWZ.ajaxDone()
* <form action="/user.do?method=save" οnsubmit="return validateCallback(this, navTabAjaxDone)">
*
* form提交后返回json数据结构statusCode=DWZ.statusCode.ok表示操作成功, 做页面跳转等操作. statusCode=DWZ.statusCode.error表示操作失败, 提示错误原因.
* statusCode=DWZ.statusCode.timeout表示session超时,下次点击时跳转到DWZ.loginUrl
* {"statusCode":"200", "message":"操作成功", "navTabId":"navNewsLi", "forwardUrl":"", "callbackType":"closeCurrent", "rel"."xxxId"}
* {"statusCode":"300", "message":"操作失败"}
* {"statusCode":"301", "message":"会话超时"}
*/
function navTabAjaxDone(json)
* navTabAjaxDone是DWZ框架中预定义的表单提交回调函数.
* 服务器转回navTabId可以把那个navTab标记为reloadFlag=1, 下次切换到那个navTab时会重新载入内容.
* callbackType如果是closeCurrent就会关闭当前tab
* 只有callbackType="forward"时需要forwardUrl值
* navTabAjaxDone这个回调函数基本可以通用了,如果还有特殊需要也可以自定义回调函数.
* 如果表单提交只提示操作是否成功, 就可以不指定回调函数. 框架会默认调用DWZ.ajaxDone()
* <form action="/user.do?method=save" οnsubmit="return validateCallback(this, navTabAjaxDone)">
*
* form提交后返回json数据结构statusCode=DWZ.statusCode.ok表示操作成功, 做页面跳转等操作. statusCode=DWZ.statusCode.error表示操作失败, 提示错误原因.
* statusCode=DWZ.statusCode.timeout表示session超时,下次点击时跳转到DWZ.loginUrl
* {"statusCode":"200", "message":"操作成功", "navTabId":"navNewsLi", "forwardUrl":"", "callbackType":"closeCurrent", "rel"."xxxId"}
* {"statusCode":"300", "message":"操作失败"}
* {"statusCode":"301", "message":"会话超时"}
*/
{
DWZ.ajaxDone(json);
if (json[DWZ.keys.statusCode] == DWZ.statusCode.ok)
{
if (json.navTabId)
{ //把指定navTab页面标记为需要“重新载入”。注意navTabId不能是当前navTab页面的
navTab.reloadFlag(json.navTabId);
//就像上面的一个文章中所说的,一个常常希望的功能就是,新打开的页面编辑完成后,
//列表页面也会刷新,但是这里reloadFlag方式设置重新载入会跳回初始界面,不会刷新
//当前页列表.
//下面的else分支中,会刷新当前分页的列表。但是在这里调用navTabPageBreak也不能
//实现,因为navTabPageBreak的代码里还是会调用getCurrentPanel。
}
else
{ //重新载入当前navTab页面
var $pagerForm = $("#pagerForm", navTab.getCurrentPanel());
var args = $pagerForm.size()>0 ? $pagerForm.serializeArray() : {}
navTabPageBreak(args, json.rel);
//返回的json中如果木有指定navTabId,就会走上面这个esle分支,navTabPageBreak中,重新获取
//当前页面上的form然后提交,能够保证刷新后停留在当前页面上。
}
if ("closeCurrent" == json.callbackType)
{
setTimeout(function(){navTab.closeCurrentTab(json.navTabId);}, 100);
}
else if ("forward" == json.callbackType)
{
navTab.reload(json.forwardUrl);
}
else if ("forwardConfirm" == json.callbackType)
{
alertMsg.confirm(json.confirmMsg || DWZ.msg("forwardConfirmMsg"),
{
okCall: function()
{
navTab.reload(json.forwardUrl);
},
cancelCall: function()
{
navTab.closeCurrentTab(json.navTabId);
}
});
}
else
{
navTab.getCurrentPanel().find(":input[initValue]").each(function()
{
var initVal = $(this).attr("initValue");
$(this).val(initVal);
});
}
}
}
//至少从这个函数里,看不出来应该怎样的简便的实现记住查询条件的刷新列表页。
//上面文章里的方法又太麻烦。一个简单的近似方法是: