Iteration variable in JSF / Richfaces Iteration

Well, that should be interesting, I think. I want to minimize the number of calls for my Seam component inside an iteration. I am using Seam 2.2.1.CR1, Richfaces 3.3.3.Final, JSF 1.2 and Facelets.

Please see the following Facelet snippet:

<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> 

In the code above, I compute the attribute (here is rowspan, but it doesn't really matter, it can be any attribute or value at all, so please don't focus on that), evaluating the EL expression. As you can see, the method that evaluates the value takes the current prod as an argument.

I did an internal optimization in the rowspan Seam component, and it saves all the calculated values ​​for the products in the HashMap. So, when the EL expression is evaluated in the second rich:column , rowspan first looks up the already calculated value in the HashMap and returns it instead of re-evaluating it again and again.

Although this is better than recalculating over and over, I still have to make a call for the Seam component. Is there a way to somehow call the Seam component only once and somehow save the calculated value for the current iteration?

Similarly, Java will define a variable inside the loop at each iteration and reuse it during the iteration.

Note. I have already done other Seam-oriented optimizations, such as @BypassInterceptors, the Seam component is in the EVENT area, so there is no hierarchical search, etc.

+4
source share
1 answer

Is there a way to somehow call the Seam component only once and somehow save the calculated value for the current iteration?

Of course, theoretically.

But I'm not sure I fully understand your question. What joint component are you talking about? rowspan ?

If so, then yes, it is called every time you call it, which makes sense. You are looping on the dataTable and on every row that you call.

Without the details of what you are trying to do, it is difficult to offer an answer. Is the code slow? That is why you need to further optimize?

Update

Try this, although I'm not sure if it works

 <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> 

Second update

So, if you do not change your code to @Out, @Factory, @Unwrap or similar, then this will always be evaluated every time it runs. This is how JSF works.
That's why they say you should do this in your getters, because the JSF will call it for each phase of the JSF.

 public List<Foo> getFoo() { if(this.field != null) { field = (List)entityManager.createQuery("from Foo").getResultList(); } return this.field; } 

If you did not cache the list and check the null value, JSF would fall into the database for each phase and for each row in the data table.

So this is just what you need to live with.

+1
source

Source: https://habr.com/ru/post/1337325/


All Articles