JFinal自定義模板指令AjaxPortal-實現頁面區域異步加載與刷新

項目背景:一個頁面上關聯了多個子表的信息,需要同時在一個界面上讀取出來,如果是單純的讀取顯示沒有任何交互的話,可以直接後臺讀取數據,前端頁面循環渲染顯示就OK,但是項目需求是需要與頁面上子表數據有CURD操作交互,看下圖:

前提:項目裏不使用自帶數據加載和刷新功能的table。就使用普通的table,也不使用Vue.js這種前端框架。

需要在一個界面上實現各子表的增刪改查,單個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學院QQ羣:362557641 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章