我打算使用应用程序范围的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之间共享?
答案 0 :(得分:1)
如果#{viewScopedBean.rowCount}
在视图构建期间可用(即在@PostConstruct
中设置),那么您可以使用<c:set>
评估一次EL表达式并将其存储在request
中},view
,session
或application
范围(如果未指定范围,则默认为无范围并充当&#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;
}