【JPress】SmartField

2021SC@SDUSC

目录

2021SC@SDUSC

一、Render

1.SmartFieldRender

2.DateRender

二、SmartField

1.SmartField

2. SmartFieldRenderFactory


一、Render

1.SmartFieldRender

渲染器接口,JPress的渲染器都要实现SmartFieldRender接口,通过其onRender()方法来生成 html 的内容。

public interface SmartFieldRender {
    public String onRender(SmartField field, Object value);
}

JPress的渲染器有如下:

 

2.DateRender

DateRender是JPress模板的Input 输入框的渲染器,它自定义了input的模板属性protected static String template:

public class DateRender implements SmartFieldRender {
​
    protected static String template = "" +
            "<div class=\"form-group row\">\n" +
            "    <label class=\"col-sm-2 col-form-label\">{label}</label>\n" +
            "    <div class=\"col-sm-6\">\n" +
            "        <input type=\"text\" class=\"form-control date\"\n" +
            "               id=\"{id}\"\n" +
            "               name=\"{name}\"\n" +
            "               data-date-format=\"yyyy-mm-dd\"\n" +
            "               placeholder=\"{placeholder}\" value=\"{value}\" {attrs}/>\n" +
            "        <p class=\"text-muted\">{helpText}</p>\n" +
            "    </div>\n" +
            "</div>";
​
    @Override
    public String onRender(SmartField field, Object value) {
        return RenderKit.render(template, field, value);
    }
​
}

再通过自己的onRender方法把输入框模板渲染出去,具体返回一个RenderKit.render(template, field, value)。RenderKit.render(template, field, value)的具体方法体如下:

public static String render(String template, SmartField field, Object value) {
    if (StrUtil.isBlank(template)) {
        return template;
    }
​
    template = replace(template, "{label}", field.getLabel());
    template = replace(template, "{id}", field.getId());
    template = replace(template, "{name}", field.getName());
    template = replace(template, "{placeholder}", field.getPlaceholder());
    template = replace(template, "{value}", value == null ? field.getValue() : value);
    template = replace(template, "{helpText}", field.getHelpText());
    template = replace(template, "{attrs}", field.getAttrs());
​
    return template;
}

很明显,这个方法可以把input输入框模板的label、id、name等属性替换掉,形成自己的模板。那么,SmartField field又是什么呢?

二、SmartField

1.SmartField

SmartField也是SmartField包下的一个类,结构如下:

public class SmartField {
​
    public static final String TYPE_INPUT = "input";
    public static final String TYPE_TEXTAREA = "textarea";
    public static final String TYPE_SELECT = "select";
    public static final String TYPE_CHECKBOX = "checkbox";
    public static final String TYPE_SWITCH = "switch";
    public static final String TYPE_RADIO = "radio";
    public static final String TYPE_IMAGE = "image";
    public static final String TYPE_FILE = "file";
    public static final String TYPE_DATE = "date";
    public static final String TYPE_DATETIME = "datetime";
​
​
    private String id;                 
    private String label;              
    private String name;               
    private String placeholder;         
    private String type;                
    private String value;              
    private String valueText;           
    private String helpText;            
    private String attrs;               
    private int orderNo;                x
    private SmartFieldRender render;    
​
    ......
​
    public SmartField addAttr(String key, Object value) {
        StringBuilder s = new StringBuilder()
                .append(key)
                .append("=\"")
                .append(value.toString())
                .append("\" ");
        this.attrs = this.attrs == null
                ? s.toString()
                : this.attrs + s.toString();
        return this;
    }
​
​
​
    public SmartFieldRender getRender() {
        return render == null
                ? SmartFieldRenderFactory.getRender(type)
                : render;
    }
​
​
    public String render() {
        if (StrUtil.isBlank(this.name)) {
            return getRender().onRender(this, null);
        }
​
        Object data = doGetDataFromControllerByName(this.name);
        return getRender().onRender(this, data);
    }
​
    public Object doGetDataFromControllerByName(String name) {
        ......
    }
​
​
}

可以发现这个类拥有大部分模板的属性,比如模板的id、标题、占位符、类型等,其中特别留意attrs属性,它为特殊模板留了其他的属性,例如 "rows" = "3"。可以发现attrs属性是一个字符串,通过addAttr()方法可以发现attrs属性的具体结构:

public SmartField addAttr(String key, Object value) {
    StringBuilder s = new StringBuilder()
            .append(key)
            .append("=\"")
            .append(value.toString())
            .append("\" ");
    this.attrs = this.attrs == null
            ? s.toString()
            : this.attrs + s.toString();
    return this;
}

它把key放在StringBuilder的头部,把value给toString后,保存在StringBuilder的尾部,所以可以了解到attrs的结构大概是key="value.toString()"的格式。

render属性是上文提到的SmartFieldRender接口对象,通过代码发现每个属性的render可以从SmartFieldRenderFactory获得。

public SmartFieldRender getRender() {
    return render == null
            ? SmartFieldRenderFactory.getRender(type)
            : render;
}

2. SmartFieldRenderFactory

渲染器工厂,负责为模板提供渲染器。发现它有个静态私有属性renderMap,用于保存工厂中的渲染器。

public class SmartFieldRenderFactory {
​
    private static Map<String, SmartFieldRender> renderMap = new ConcurrentHashMap<>();
​
    static {
        registerRender(SmartField.TYPE_INPUT, new InputRender());
        registerRender(SmartField.TYPE_TEXTAREA, new TextareaRender());
        registerRender(SmartField.TYPE_SELECT, new SelectRender());
        registerRender(SmartField.TYPE_CHECKBOX, new CheckboxRender());
        registerRender(SmartField.TYPE_SWITCH, new SwitchRender());
        registerRender(SmartField.TYPE_RADIO, new RadioRender());
        registerRender(SmartField.TYPE_IMAGE, new ImageRender());
        registerRender(SmartField.TYPE_FILE, new FileRender());
        registerRender(SmartField.TYPE_DATE, new DateRender());
        registerRender(SmartField.TYPE_DATETIME, new DatetimeRender());
    }
​
​
    public static void registerRender(String type, SmartFieldRender render) {
        renderMap.put(type, render);
    }
​
    public static SmartFieldRender getRender(String type) {
        return renderMap.get(type);
    }
​
    public static Map<String, SmartFieldRender> getRenderMap() {
        return renderMap;
    }
}

提供源码发现,工厂一开始就初始化(registerRender)各个类型的工厂,并且通过getRender()方法向外提供渲染器。

以上为JPress的模板类、模板渲染的实现代码分析。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值