远离参数化的getter

时间:2014-10-13 09:31:13

标签: jsf primefaces jsf-2.2

我打算使用应用程序范围的bean(作为公共bean)返回rowsPerPageTemplate 5,10,15,20属性的值,如<p:dataTable> - 逗号分隔的值列表指示页面大小<p:dataTable var="row" value="#{viewScopedBean}" lazy="true" pageLinks="10" rows="10" rowsPerPageTemplate="#{pageTemplate.getCommonTemplate(viewScopedBean.rowCount)}"> ... </p:dataTable>

pageTemplate

@ManagedBean @ApplicationScoped public final class PageTemplate { private static final int pageSize = 10; public PageTemplate() {} private static String getTemplate(int rowCount) { if (pageSize >= rowCount) { return String.valueOf(pageSize); } int sum = 0; int pages = (int) Math.ceil(rowCount / (double) pageSize); pages = pages >= 100 ? 100 : pages; String templateString = ""; for (int i = 0; i < pages; i++) { sum += pageSize; templateString += sum + ","; } return new String(templateString.substring(0, templateString.length() - 1)); } public String getCommonTemplate(int rowCount) { return getTemplate(rowCount); } } bean:

getCommonTemplate()

bean和XHTML是不言自明的。参数化方法#{}由EL表达式getCommonTemplate()引用,因此被多次调用。

虽然该方法包含的逻辑非常便宜,但在bean中使用getter方法包装这种逻辑不应该是最好的做法。

<p:dataTable>方法中的代码是否可以移动到保证只执行一次的地方(这不应该是ViewScopedBean - getCommonTemplate()当前使用的bean,因为<p:dataTable>方法包含的代码应该在使用{{1}})的所有bean之间共享?

1 个答案:

答案 0 :(得分:1)

如果#{viewScopedBean.rowCount}在视图构建期间可用(即在@PostConstruct中设置),那么您可以使用<c:set>评估一次EL表达式并将其存储在request中},viewsessionapplication范围(如果未指定范围,则默认为无范围并充当&#34;别名&#34;)。

<c:set var="rowsPerPageTemplate" value="#{pageTemplate.getCommonTemplate(viewScopedBean.rowCount)}" scope="view" />
<p:dataTable ...
    rowsPerPageTemplate="#{rowsPerPageTemplate}">
    ...
</p:dataTable>

但是,如果它在视图构建期间不可用(在LazyDataModel的情况下显然是这样),那么最好的办法是将结果缓存到#{pageTemplate}。< / p>

private static final Map<Integer, String> TEMPLATES_BY_ROW_COUNT = new HashMap<>();

public String getCommonTemplate(int rowCount) {
    String template = TEMPLATES_BY_ROW_COUNT.get(rowCount);

    if (template == null) {
        template = getTemplate(rowCount);
        TEMPLATES_BY_ROW_COUNT.put(rowCount, template);
    }

    return template;
}