Optimization JSF/Richfaces迭代中的迭代范围变量?

Optimization JSF/Richfaces迭代中的迭代范围变量?,optimization,jsf,richfaces,seam,Optimization,Jsf,Richfaces,Seam,好的,我想这应该是一个有趣的例子。我想尽量减少迭代中对Seam组件的调用次数。我正在使用Seam 2.2.1.CR1、Richfaces 3.3.3.Final、JSF 1.2和Facelets 请查看以下Facelet片段: <rich:datatable value="#{myBean.products}" var="prod"> <rich:column rowspan="#{rowspan.calcHomePageProductRowspan(prod)}">

好的,我想这应该是一个有趣的例子。我想尽量减少迭代中对Seam组件的调用次数。我正在使用Seam 2.2.1.CR1、Richfaces 3.3.3.Final、JSF 1.2和Facelets

请查看以下Facelet片段:

<rich:datatable value="#{myBean.products}" var="prod">

<rich:column rowspan="#{rowspan.calcHomePageProductRowspan(prod)}">
    #{prod.name}
</rich:column>

<rich:column rowspan="#{rowspan.calcHomePageProductRowspan(prod)}">
    #{prod.number}
</rich:column>

...

<rich:column rowspan="#{rowspan.calcHomePageProductRowspan(prod)}">
    #{prod.somethingElse1}
</rich:column>

<rich:column rowspan="#{rowspan.calcHomePageProductRowspan(prod)}">
    #{prod.somethingElse2}
</rich:column>

...

<rich:column rowspan="#{rowspan.calcHomePageProductRowspan(prod)}">
    #{prod.somethingElse3}
</rich:column>

</rich:datatable>

#{prod.name}
#{prod.number}
...
#{prod.somethingels1}
#{prod.somethingels2}
...
#{prod.somethingeles3}
在上面的代码中,我通过计算EL表达式来计算一个属性(这里是rowspan,但这并不重要,它可以是任何属性或值,所以请不要关注这一点)。如您所见,计算值的方法将当前prod作为参数

我在
rowspan
Seam组件中进行了内部优化,它将产品的所有已计算值保存在HashMap中。因此,当在第二个
rich:column
处计算EL表达式时,
rowspan
首先在HashMap中查找已计算的值,并返回该值,而不是重新计算

尽管这比重新计算要好,但我仍然需要调用Seam组件。有没有办法只调用Seam组件一次,并为当前迭代保留计算值

与Java类似的是,在每次迭代时在循环中定义一个变量,并在整个迭代过程中重用它

注意:我已经做了其他面向Seam的优化,例如@BypassInterceptors,Seam组件在事件范围内,因此没有发生分层查找等

有没有办法只调用Seam组件一次,并为当前迭代保留计算值

当然,理论上

但我不确定我是否完全理解你的问题。你说的是哪个接缝组件<代码>行span

如果是这样的话,那么是的,每次你调用它时它都会被调用,这很有意义。您在一个数据表中循环,并为每一行调用它

如果不知道更多关于你想做什么的细节,就很难给出答案。代码慢吗?这就是您需要进一步优化的原因吗

更新

试试这个,虽然我不确定它是否有效

<rich:dataTable value="#{myBean.products}" var="prod">
   <ui:param name="myrowspan" value="#{rowspan.calcHomePageProductRowspan(prod)}"/>
   <rich:column rowspan="#{myrowspan}">
     #{prod.name}
   </rich:column>
</rich:dataTable>

#{prod.name}
第二次更新

因此,如果您不将代码更改为@Out、@Factory、@Unwrap或类似代码,那么每次运行时都会对其进行评估。这就是JSF的工作原理。
这就是为什么他们说您应该在getter中这样做,因为JSF将在每个JSF阶段调用它

public List<Foo> getFoo() {
  if(this.field != null) { 
    field = (List)entityManager.createQuery("from Foo").getResultList();
  } 
  return this.field; 
}
公共列表getFoo(){ 如果(this.field!=null){ field=(List)entityManager.createQuery(“来自Foo”).getResultList(); } 返回此.field; } 如果没有缓存列表并检查null,JSF将针对数据表中的每个阶段和每一行访问数据库


因此,这只是你必须接受的东西

JSP还是Facelets?如果是JSP,它将在这里结束(不,JSTL
UIData
组件中无法帮助)。如果是Facelets,请使用
。我使用Facelets。编辑了问题。是的,rowspan是Seam组件。您是否尝试过
,然后在rowspan标记中使用此myrowspan?但我不确定它是否有效。对不起,它没有,我以为它有效:-(好的。那么我认为这不可能不重写代码,使用
@Factory
或类似的东西。这就是JSF的创建方式。每个EL都会被计算,如果seam在这些特殊的上下文中找不到它,它就会传播。所以最好的办法就是使用你正在做的缓存