项目背景:一个页面上关联了多个子表的信息,需要同时在一个界面上读取出来,如果是单纯的读取显示没有任何交互的话,可以直接后台读取数据,前端页面循环渲染显示就OK,但是项目需求是需要与页面上子表数据有CURD操作交互,看下图:
前提:项目里不使用自带数据加载和刷新功能的table。就使用普通的table,也不使用Vue.js这种前端框架。
点击打开gif图看效果:
http://www.xiaomuedu.com/ueditor/jsp/upload/image/20180527/1527414814138022575.gif
需要在一个界面上实现各子表的增删改查,单个Table的数据区域Html片段自行更新,就需要用到AjaxPortal模式。
AjaxPortal模式简介:
使用ajax加载Html片段Append到指定的DIV区域,完成局部刷新效果。
实现细节:
1、JavaScript 基于Jquery封装ajax加载Html片段的工具库
/** * 自动Ajax加载内容的Portal */ ;(function($){ $.extend($.fn, { ajaxPortal:function(replaceBody,url){ return this.each(function(){ var portal=$(this); var l_url=""; if(url){ l_url=url; }else{ l_url=portal.data("url") } if(l_url.indexOf("?")!=-1){ l_url=l_url+"&t="+new Date().getTime(); }else{ l_url=l_url+"?t="+new Date().getTime(); } var autoload=portal.data("autoload"); if(autoload==undefined){ autoload=true; } if((replaceBody==undefined&&autoload)||(replaceBody!=undefined)){ $.get(l_url,function(html){ if(replaceBody){ portal.empty().html(html); }else{ portal.append(html); } }); } }); } }); })(jQuery);
2、上面js库搞定后,在没有自定义JFinal模板引擎指令之前,是可以直接使用html的,代码如下:
<div data-ajaxportal data-url="你需要加载html片段的具体action地址" id="myAjaxPortal"></div>
3、上面Html标签写完 页面上调用一下js就能实现自动加载html片段了
$("#myAjaxPortal").ajaxPortal();
JFinal自定义指令扩展之后 可以不写html了,先来看看 自定义指令如何调用
<!-- 发展数据加载 --> #ajaxPortal("你的action Url","project_growth_portal") <!-- 大事记加载 --> #ajaxPortal("你的action Url","project_thingrecord_portal") <!-- 细节谈加载 --> #ajaxPortal("你的action Url","project_detail_portal")
说明:一共有三个参数的,第一个是URL地址,第二个参数是给这个DIV Portal设置一个ID,第三个是指定是否默认自动执行加载
经过封装可以实现,一个参数的时候默认自动加载 ID不要,两个参数的时候 指定了ID和URL 默认自动加载 三个参数就是完全自己决定是否自动执行加载。
上代码吧:
import java.io.IOException; import com.jfinal.template.Directive; import com.jfinal.template.Env; import com.jfinal.template.expr.ast.Expr; import com.jfinal.template.expr.ast.ExprList; import com.jfinal.template.io.Writer; import com.jfinal.template.stat.ParseException; import com.jfinal.template.stat.Scope; public class AjaxPortalDirective extends Directive { private Expr portalIdExpr; private Expr urlExpr; private Expr autoLoadExpr; private int paraNum; public void setExprList(ExprList exprList) { this.paraNum = exprList.length(); if (paraNum > 3) { throw new ParseException("Wrong number parameter of #ajaxPortal directive, three parameters allowed at most", location); } if (paraNum == 1) { this.urlExpr = exprList.getExpr(0); } else if (paraNum == 2) { this.urlExpr = exprList.getExpr(0); this.portalIdExpr = exprList.getExpr(1); } else if (paraNum == 3) { this.urlExpr = exprList.getExpr(0); this.portalIdExpr = exprList.getExpr(1); this.autoLoadExpr = exprList.getExpr(2); } } public void exec(Env env, Scope scope, Writer writer) { if (paraNum == 0) { outputNothing(env, writer); } else if (paraNum == 1) { outputNormalAjaxPortal(env, scope, writer); } else if (paraNum == 2) { outputNormalAjaxPortalWithPortalId(env, scope, writer); } else if (paraNum == 3) { outputFullAjaxPortal(env, scope, writer); } } /** * 输出空字符 * @param env * @param writer */ private void outputNothing(Env env, Writer writer) { } /** * 输出自动加载的仅指定Url的ajaxPortal代码 * @param env * @param scope * @param writer */ private void outputNormalAjaxPortal(Env env,Scope scope, Writer writer) { Object value=this.urlExpr.eval(scope); if(value!=null){ try { writer.write("<div data-ajaxportal data-url='"); writer.write(value.toString()); writer.write("'></div>"); } catch (IOException e) { e.printStackTrace(); } } } /** * 输出自动加载的带有portalId和url的ajaxPortal代码 * @param env * @param scope * @param writer */ private void outputNormalAjaxPortalWithPortalId(Env env,Scope scope, Writer writer) { Object url=this.urlExpr.eval(scope); Object portalId=this.portalIdExpr.eval(scope); if(url!=null&&portalId!=null){ try { writer.write("<div data-ajaxportal data-url='"); writer.write(url.toString()); writer.write("' id='"); writer.write(portalId.toString()); writer.write("'></div>"); } catch (IOException e) { e.printStackTrace(); } } } /** * 输出带有portalId和url的ajaxPortal代码 * 可以设置是否自动加载 * @param env * @param scope * @param writer */ private void outputFullAjaxPortal(Env env,Scope scope, Writer writer) { Object url=this.urlExpr.eval(scope); Object portalId=this.portalIdExpr.eval(scope); Object autoload=this.autoLoadExpr.eval(scope); if(url!=null&&portalId!=null&&autoload!=null){ try { writer.write("<div data-ajaxportal data-autoload='"); writer.write(autoload.toString()); writer.write("' data-url='"); writer.write(url.toString()); writer.write("' id='"); writer.write(portalId.toString()); writer.write("'></div>"); } catch (IOException e) { e.printStackTrace(); } } } }
总结:自定义指令可以配合HTML和JS 完成很多强大功能做出很好的用户体验。
这就是AjaxPortal自定义指令的代码,文章里发的是截图,如果需要全部demo源码,请关注【JFinal学院】公众号:jfinalxueyuan。
回复:ajaxportal 关键词 获取源码下载地址。
希望得到您的转发分享与关注,打造JFinal学院-JFinal社区自己的学院。
————————————————————————————————
如果还不明白,可以微信联系我: