Thanks Adam. That makes good sense.
All that is needed now is a volunteer to implement it :-).
I might have a go if I can find some spare time but it won't be soon. I
will try to find time to record this as an enhancement in JIRA so it
doesn't get lost.
Regards,
Simon
Adam Winer wrote:
Technically, rendered is supposed to be:
- Constant across encodeBegin()/encodeChildren()/encodeEnd()
- Constant across processDecodes()/processValidators()/
processUpdateModel().
Unfortunately, the latter doesn't help - since a component inside
a table would have processDecodes() called repeatedly,
then processValidators() repeatedly, etc. - and "rendered"
could be different from one row to the next.
But the former should be fine - if you always fetch and
store the value in encodeBegin() (whether or not encodeBegin()
has previously been called), then use that in encodeChildren()
and encodeEnd(), you should be fine.
-- Adam
On 5/8/07, Simon Kitching <[EMAIL PROTECTED]> wrote:
Andrew, are you just stating what currently happens or are you saying
that there is a *reason* for evaluating "rendered" in encodeBegin,
encodeChildren and encodeEnd?
I can't initially see any reason why it would need to be evaluated more
than once.
UIComponentBase does indeed call isRendered in encodeBegin,
encodeChildren and encodeEnd. It also implements isRendered as an
evaluation of the EL expression (myfaces 1.1.3 implementation).
But As Wesley asks, why would it ever make sense for rendered to be true
in encodeBegin, but false in encodeEnd? I cannot see any way that would
be useful, so why not just compute it once then cache it somewhere for
the rest of that render cycle (eg in a "transient" member of the
component)? This would be a significant performance boost..
Wesley, your proposed modification which stores the rendered state into
_rendered is not good because setting _rendered will permanently
override the rendered EL expression, not just for the current render
cycle but for the lifetime of that component. What is needed is to
figure out when the first call to isRendered is done *during the render
cycle* and then cache that until rendering finishes. Note that
isRendered is also called during postback processing, and it's perfectly
reasonable to change this value between postback and render so caching
really should only be done between encodeBegin() and encodeEnd(). So
implementing this optimisation is a little tricky - but not impossible
I'm sure.
Regards,
Simon
Andrew Robinson wrote:
> At the very least rendered is called during encodeBegin,
> encodeChildren, and encodeEnd.
>
> On 5/8/07, Wesley Hales <[EMAIL PROTECTED]> wrote:
>> Hello - Why do we continually call isRendered after encodeBegin()?
>> Once the
>> begin tag is written out, it shouldn't matter what the body and end
>> rendered
>> states are.
>>
>> Facelets 1.1.11
>> Myfaces 1.1.5 & 1.2
>>
>> So if I have <t:div rendered="#{MyBean.alerts > 0}"...
>> The #{MyBean.alerts method is called 5 times! and it is like this for
>> every
>> EL eval on the page. I do know that EL can only bind to the
>> FaceletsContext
>> and no other scopes... So are there any other options than what I have
>> listed below?
>>
>> 1. Tried to modify MyFaces src in UIComponentBase:
>> public boolean isRendered()
>> {
>> if(_rendered == null){
>>
>> // our modification! Only compute the rendered value
once, and
>> cache for the rest of the lifecycle.
>> Boolean rend = getExpressionValue("rendered", _rendered,
>> DEFAULT_RENDERED);
>> _rendered = rend.booleanValue();
>> }
>> return _rendered;
>> }
>> This didn't work :( - Something happend to A4J and we had no ideas
>> what the
>> implication would be on all components.
>>
>> 2. Tried using Facelets <ui:param and <c:set to store the EL in a page
>> scoped variable, then have the variable evaluated in the rendered
>> attribute.
>> This didn't work either because it is on FacesContext.
>>
>> So this may just be me not fully understanding what JSF does
behind the
>> scenes of component rendering, or some people say that the spec is
>> screwed
>> up when it comes to this. I'm sure some of the pros can help me out
>> here :).
>>
>> Thx,
>> Wesley Hales