像#render指令一樣可以動態(tài)參數又支持調用子模板中的函數

也許你在jfinal的官方文檔中看到enjoy指令部分有說到#render指令:

render指令中#define定義的模板函數只在其子模板中有效,在父模板中無效,這樣設計非常有利于模塊化
舉個例子:

layout.html

#define layout()
#@content()
#end

index.html

#render("layout.html")
#@layout()
#define content()
顯示xxx
#end

你會發(fā)現layout()函數是調用不到的,這就是和#include指令不一樣的地方了。

那有人會說為什么不直接使用#include指令呢, 因為有動態(tài)變換模板的需求,而#include是不支持的; 當有l(wèi)ayout1.html, layout2.html多個布局配置,后臺根據配置加載的,所以需要#render指令接受動態(tài)的參數。這時候自定義指令上場了,在群里請教波總后,給的幾個方案,只有自定義指令符合我的需求。

找到jfinal源碼com.jfinal.template.ext.directive.RenderDirective,參考他的稍作改動即可。

新建類 MyRenderDirective extends Directive,拷貝RenderDirective的源碼,修改parseSubStat()和SubStat類

private SubStat parseSubStat(Env env, String subFileName) {
        EngineConfig config = env.getEngineConfig();
        ISource subFileSource = config.getSourceFactory().getSource(config.getBaseTemplatePath(), subFileName, config.getEncoding());
        try {
            StatList subStatList = (new Parser(env, subFileSource.getContent(), subFileName)).parse();
            return new SubStat(env, subStatList.getActualStat(), subFileSource);
        } catch (Exception var7) {
            throw new ParseException(var7.getMessage(), this.location, var7);
        }
    }
    public static class SubStat extends Stat {
        public Env env;
        public Stat stat;
        public ISource source;
        public SubStat(Env env, Stat stat, ISource source) {
            this.env = env;
            this.stat = stat;
            this.source = source;
        }
        public void exec(Env env, Scope scope, Writer writer) {
            this.stat.exec(this.env, scope, writer);
        }
    }

只要把指令添加進引擎即可engine().addDirective("myRender", MyRenderDirective.class);

現在終于可以愉快的玩耍了,layoutPath是變量。

myRender(layoutPath)

其他方案我也分享一下吧,這得益于enjoy的精巧強大,

方案一:

1: layout 文件中不使用 #define layout() , 而是直接寫 html , 例如:

   <html>

      ….

     #@main()

   </html>

2: 主頁面中直接 #define main()

   #render( 動態(tài) layout 文件名 )

   #define main()

     …

   #end

方案二:

第二種辦法是為 render 指令傳入函數名, 或者約定一個函數名, 改為在子模板中調用,例如:

子模板.html

#define layout()

    ….

    #@main()

#end

#@layout()

父模板:

#render( 子模板.html )

#define main()

 …

#end

相當于是將 #@layout 挪到子模板中去調用

如果函數名是動態(tài)的,也可以這樣:

子模板.html

#define layout()

    ….

    #@main()

#end

#call(funcName)

父模板:

#render( 子模板.html ,  funcName = "layout")

#define main()

 …

#end

方案三:

最后一個辦法,也是最蠢的辦法:

#if (…)

#include(…)

#else if (…)

#include(…)

#else if (…)

#include(…)

#else if (…)

#include(…)

#end

#@layout()

用 if 分支,窮盡所有動態(tài)模板,然后在 #include 中使用 String 常量

以上都是波總提供的方案,從14年關注jfinal以來,波總一直非常熱心的分享和解答各種問題。

真心覺得enjoy功能很少, 但組合起來是無比強大,極簡設計一直是jfinal推崇的,深深的領教了。

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容