原創(chuàng)聲明:本文為作者原創(chuàng),未經(jīng)允許不得轉(zhuǎn)載,經(jīng)授權(quán)轉(zhuǎn)載需注明作者和出處
項目背景:一個頁面上關(guān)聯(lián)了多個子表的信息,需要同時在一個界面上讀取出來,如果是單純的讀取顯示沒有任何交互的話,可以直接后臺讀取數(shù)據(jù),前端頁面循環(huán)渲染顯示就OK,但是項目需求是需要與頁面上子表數(shù)據(jù)有CURD操作交互,看下圖:
前提:項目里不使用自帶數(shù)據(jù)加載和刷新功能的table。就使用普通的table,也不使用Vue.js這種前端框架。**
需要在一個界面上實現(xiàn)各子表的增刪改查,單個Table的數(shù)據(jù)區(qū)域Html片段自行更新,就需要用到AjaxPortal模式。
AjaxPortal模式簡介:
使用ajax加載Html片段Append到指定的DIV區(qū)域,完成局部刷新效果。
實現(xiàn)細節(jié):
1、JavaScript 基于Jquery封裝ajax加載Html片段的工具庫
/**
* 自動Ajax加載內(nèi)容的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標簽寫完 頁面上調(diào)用一下js就能實現(xiàn)自動加載html片段了
$("#myAjaxPortal").ajaxPortal();
JFinal自定義指令擴展之后 可以不寫html了,先來看看 自定義指令如何調(diào)用
<!-- 發(fā)展數(shù)據(jù)加載 -->
#ajaxPortal("你的action Url","project\_growth\_portal")
<!-- 大事記加載 -->
#ajaxPortal("你的action Url","project\_thingrecord\_portal")
<!-- 細節(jié)談加載 -->
#ajaxPortal("你的action Url","project\_detail\_portal")
說明:一共有三個參數(shù)的,第一個是URL地址,第二個參數(shù)是給這個DIV Portal設(shè)置一個ID,第三個是指定是否默認自動執(zhí)行加載
經(jīng)過封裝可以實現(xiàn),一個參數(shù)的時候默認自動加載 ID不要,兩個參數(shù)的時候 指定了ID和URL 默認自動加載 三個參數(shù)就是完全自己決定是否自動執(zhí)行加載。
上代碼吧:
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代碼
* 可以設(shè)置是否自動加載
* @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();
}
}
}
}
總結(jié):自定義指令可以配合HTML和JS 完成很多強大功能做出很好的用戶體驗。
這就是AjaxPortal自定義指令的代碼,文章里發(fā)的是截圖,如果需要全部demo源碼,請關(guān)注【JFinal學(xué)院】公眾號:jfinalxueyuan。
回復(fù):ajaxportal 關(guān)鍵詞 獲取源碼下載地址。
JFinal學(xué)院QQ群:362557641