enjoy共享对象名和Controller中返回的参数名相同时如何分别获取两个值

一、场景

在configEngine中添加了一个共享对象,名称标记为“site”,该对象中有一个“siteUrl”的静态属性,如下图。理论上,可以在html界面通过#(site.siteUrl??)输出静态变量的值。

image.png

image.png

在Controller的action中返回一个参数对象Site,使用的参数名是“site”,该对象也有一个属性“siteUrl”,如下图。理论上,也可以在该action返回的界面上通过#(site.siteUrl??)输出Site对象的siteUrl值。

image.png

image.png

二、问题

结合上面的描述,我在pageSiteEdit.html页面使用#(site.siteUrl??)输出时,好像只是输出对象Site的siteUrl属性,当该属性没有值时直接输出空字符串,并没有再尝试输出共享对象site的静态属性siteUrl。

在该页面想要输出共享对象site的siteUrl属性应该如何处理?不修改共享对象的名称能不能行?

文档 6.3表达式 - 2、属性访问 一节提及到field 表达式取值优先次序,没有提及到共享对象属性访问顺序,是否需要体现?


请波总、各位大佬指教。

评论区

JFinal

2021-03-11 00:28

获取变量是在 Scope 的 get(Object key) 方法中,优先级是 Scope 内的 Map data 高于 shared object,源码在这里:
https://gitee.com/jfinal/jfinal/blob/master/src/main/java/com/jfinal/template/stat/Scope.java

在 get(Object key) 中设置一个断点,调试一下可以了解更深入

目前在页面直接优先获取 shared object 貌似还没有好办法,不过,你可以通过扩展指令来实现,大致如下:
public class SharedObjectDirective extends Directive {
public void exec(Env env, Scope scope, Writer writer) {
String key = exprList.getExpr(0).toString();
Object value = scope.getSharedObject(key);
write(writer, value.toString());
}
}

最后配置一下:
engine.addDriective("so", SharedObjectDirective.class);

用的时候这样:
#so(site.siteUrl)

杜福忠

2021-03-11 09:58

Shared Object扩展 我都是规定项目中 共享对象 首字母大写,然后业务中set变量都是首字母小写。 这样用起来还挺方便,共享对象一看就和java里面的类名一样,也方便找对应java源码

杜福忠

2021-03-11 10:16

@JFinal 老大,建议文档6.8 Shared Object扩展中的代码示例改为:me.addSharedObject("StrKit", new com.jfinal.kit.StrKit()); 和 #if(StrKit.isBlank(title)) 。感觉全名称使用方式更符合java开发者直觉了,虽然缩写确实会省一点按键,但是通过编辑器自定义快捷语法同样可以提高开发速度。共享再多也不会感觉乱
image.png

永字诀

2021-03-11 10:33

@杜福忠 这个方式好,我这个就是属于命名没规划好,现在有冲突了。按波总说的,现在没有更好的方式,只能是改下命名了,后续参考你这个改造下,感谢,手动点赞。

JFinal

2021-03-11 11:59

@杜福忠 这个办法极好,我现在改下文档

@永字诀 杜同学的办法是极好的, shared object 在直觉用大写开头挺好

JFinal

2021-03-11 12:02

@永字诀 具体到你的应用,改成下面这样的为好:
engine.addSharedObject("Site", new SiteInfo());

用的时候这样:
#(Site.url)

siteUrl 属性名改为 url 为好,因为有了 Site. 前缀,siteUrl 是一种重复

永字诀

2021-03-11 13:51

@JFinal 嗯嗯,准备按这个方案修改了。

热门反馈

扫码入社