我有这个页面:
<c:forEach begin="0" end="#{tareaController.tipoFuncion.filas}" step="1" var="x">
<p:row>
<c:forEach begin="0" end="#{tareaController.tipoFuncion.columnas}" step="1" var="y">
<c:choose>
<c:when test="#{tareaController.configuracionEnPosicion(x,y) ne null}">
<p:column style="width: 80px"
colspan="#{tareaController.configuracionEnPosicion(x,y).colSpan}"
rowspan="#{tareaController.configuracionEnPosicion(x,y).rowSpan}">
<p:outputLabel value="#{tareaController.atributoEnPosicion(x,y).labelAtributo}:"
rendered="#{!tareaController.validar.isBoton(tareaController.atributoEnPosicion(x, y).tipoAtributosOpcionales)}">
<c:if test="#{tareaController.configuracionEnPosicion(x,y).esObligatorio}">
*
</c:if>
</p:outputLabel>
</p:column>
<p:column colspan="#{tareaController.configuracionEnPosicion(x,y).colSpan}"
rowspan="#{tareaController.configuracionEnPosicion(x,y).rowSpan}">
<c:choose>
<c:when test="#{tareaController.validar.isSeparador(tareaController.atributoEnPosicion(x, y).tipoAtributosOpcionales)}">
<p:separator/>
</c:when>
<c:when test="#{tareaController.validar.isNumerico(tareaController.atributoEnPosicion(x,y).tipoAtributosOpcionales)}">
<pe:inputNumber decimalSeparator="#{tareaController.configuracionEnPosicion(x,y).separadorDecimal}"
thousandSeparator="#{tareaController.configuracionEnPosicion(x,y).separadorMiles}"
decimalPlaces="#{tareaController.configuracionEnPosicion(x,y).cantidadDecimales}"
disabled="#{mFuncion.soloLectura || !tareaController.tareaAceptada || tareaController.tomadaPorOtroUsuario || tareaController.configuracionEnPosicion(x,y).soloLectura}"
maxValue="#{tareaController.configuracionEnPosicion(x,y).valorMaximo}"
rendered="#{!tareaController.configuracionEnPosicion(x,y).ocultarAtributo}"
value="#{tareaController.atributoEnPosicion(x,y).valorAtributoNumerico}"
style="width: #{tareaController.configuracionEnPosicion(x,y).ancho}px; height: #{tareaController.configuracionEnPosicion(x,y).alto}px;">
<p:ajax global="false" update=":f_tarea:tabView:tab_#{tareaController.indiceTramite}:nombreRepetido, :f_tarea:b_completarT" listener="#{tareaController.validarTarea()}"/>
</pe:inputNumber>
</c:when>
<c:when test="#{tareaController.validar.isBoton(tareaController.atributoEnPosicion(x, y).tipoAtributosOpcionales)}">
<p:commandButton value="#{tareaController.atributoEnPosicion(x,y).labelAtributo}"
actionListener="#{tareaController.ejecutarWs(tareaController.configuracionEnPosicion(x,y))}"
update=":f_tarea:tabView:tab_#{tareaController.indiceTramite}:pg_funcion_#{tareaController.indiceTramite}"/>
</c:when>
<c:when test="#{tareaController.validar.isFecha(tareaController.atributoEnPosicion(x,y).tipoAtributosOpcionales)}">
<p:calendar value="#{tareaController.atributoEnPosicion(x,y).valorAtributoFecha}"
maxdate="#{tareaController.configuracionEnPosicion(x,y).fechaMaxima}"
mindate="#{tareaController.configuracionEnPosicion(x,y).fechaMinima}"
rendered="#{!tareaController.configuracionEnPosicion(x,y).ocultarAtributo}"
disabled="#{mFuncion.soloLectura || !tareaController.tareaAceptada || tareaController.tomadaPorOtroUsuario || tareaController.configuracionEnPosicion(x,y).soloLectura || tareaController.atributoEnPosicion(x,y).bloquear}"
size="20"
pattern="#{tareaController.configuracionEnPosicion(x,y).formatoFecha}">
<p:ajax global="false" update=":f_tarea:tabView:tab_#{tareaController.indiceTramite}:nombreRepetido, :f_tarea:b_completarT" listener="#{tareaController.validarTarea()}"/>
<p:ajax event="dateSelect" global="false" update=":f_tarea:tabView:tab_#{tareaController.indiceTramite}:nombreRepetido, :f_tarea:b_completarT" listener="#{tareaController.validarTarea()}"/>
</p:calendar>
</c:when>
<c:otherwise test="#{tareaController.validar.isAlfanumerico(tareaController.atributoEnPosicion(x,y).tipoAtributosOpcionales)}">
<p:inputTextarea value="#{tareaController.atributoEnPosicion(x,y).valorAtributoAlfanumerico}"
disabled="#{mFuncion.soloLectura || !tareaController.tareaAceptada || tareaController.tomadaPorOtroUsuario || tareaController.configuracionEnPosicion(x,y).soloLectura}"
rendered="#{!tareaController.configuracionEnPosicion(x,y).ocultarAtributo}"
style="width: #{tareaController.configuracionEnPosicion(x,y).ancho}px;
height: #{tareaController.configuracionEnPosicion(x,y).alto}px;
word-break: normal;">
<p:ajax global="false" update=":f_tarea:tabView:tab_#{tareaController.indiceTramite}:nombreRepetido, :f_tarea:b_completarT" listener="#{tareaController.validarTarea()}"/>
<p:ajax event="select" global="false" update=":f_tarea:tabView:tab_#{tareaController.indiceTramite}:nombreRepetido, :f_tarea:b_completarT" listener="#{tareaController.validarTarea()}"/>
</p:inputTextarea>
</c:otherwise>
</c:choose>
</p:column>
</c:when>
<c:otherwise>
<p:column>
<h:panelGroup/>
</p:column>
<p:column>
<h:panelGroup/>
</p:column>
</c:otherwise>
</c:choose>
</c:forEach>
我的想法是,我可以配置该页面并将组件放置在我想要的位置,具有许多不同的配置。它工作得很好,人们对此很满意,但我不是。如果你检查页面,我会在循环的每次运行中调用方法configuracionEnPosicion(x,y)和atributoEnPosicion(x,y)300次。并且这些方法像其他3种方法一样调用,并在x,y中查找实际配置。令人惊讶的是它不会缓慢但我觉得这是我可以避免的大量开销。
在我尝试使用各自的getter和setter将configuracionEnPosicion(x,y)和atributoEnPosicion(x,y)的结果保存在客户端的变量中之前,但由于JSTL Core标记在构建时运行,渲染时间变量未更新,导致该变量保持其最后一个值并给出不希望的行为。我的“解决方案”是实际的,但我的最后一个问题是:有没有办法存储该变量的值,所以我只能在构建时或类似的东西中保持它?我想在每个x和y位置调用这些方法只是ONCE,但是我对JSF和Primefaces的了解并不足以实现这一点。
有条件的信息:
答案 0 :(得分:3)
它似乎是JSR 107: JCACHE - Java Temporary Caching API的任务。但是你应该使用CDI bean而不是JSF托管bean。这允许您编写如下代码:
@CacheResult(cacheName = "configuracionEnPosicion")
public String configuracionEnPosicion(int x, int y){
.....
}
还需要创建META-INF / beans.xml:
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>org.jsr107.ri.annotations.cdi.CacheResultInterceptor</class>
<class>org.jsr107.ri.annotations.cdi.CachePutInterceptor</class>
<class>org.jsr107.ri.annotations.cdi.CacheRemoveEntryInterceptor</class>
<class>org.jsr107.ri.annotations.cdi.CacheRemoveAllInterceptor</class>
</interceptors>
</beans>
还需要在某处创建缓存:
@PostConstruct
public void init() {
try {
// Retrieve the system wide cache manager
CacheManager cacheManager = Caching.getCachingProvider().getCacheManager();
// Define a named cache with default JCache configuration
MutableConfiguration<String, String> configuration = new MutableConfiguration<>();
//specify expiry policy
configuration.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(Duration.ONE_MINUTE));
cache = cacheManager.createCache("configuracionEnPosicion", configuration);
} catch (Exception e) {
L.error("Can't init cache!", e);
}
}
当然,您应该选择jcache provider(ecache,infinispan,...)并为项目添加必要的依赖项。
答案 1 :(得分:1)
我在@BalusC评论之后编辑了我的答案
您可以预先计算支持bean PostConstruct方法中的所有值。
在支持bean级别声明一个二维数组:
private ReturnedObjectClass[][] precalculatedArray;
添加getter方法。
在PostConstruct方法中初始化它:
precalculatedArray = new ReturnedObjectClass[x][y];
使用PostConstruct方法中函数返回的对象填充它:
precalculatedArray[i][j] = myBigFunction(i,j);
然后,您可以使用以下方式从您的页面访问计算值:
value="#{tareaController.precalculatedArray[x][y].propertyOfReturnedObjectClass}"
答案 2 :(得分:-1)