On Mon, 2006-12-11 at 09:44 -0700, Andrew Robinson wrote:
> "When myBean.myModel.myOptions is invoked the first time, I do some
> lazy
> initialization, this might cause errors..."
> 
> I would recommend that you load this data in the on load method of
> your page. This way, if it fails, you can handle the error in any way
> you want, including redirecting to an error page.
I cannot do this, because I have to initialize the detailStamps of 
all rows separately: the details of one item cause several backend
requests that might cost money, and they definitively need time
to return (several seconds per request).

Now I wrote a CustomHtmlDataTable (extending HtmlDataTable) that
provides an additional MethodBinding "toggleDetailActionListener".

The toggleDetail method is extended so that it invokes also the method
binding if it's provided.

The hardest thing was to write the facelets MetaTagHandler that sets
the attribute on the CustomHtmlDataTable:

public final class CustomHtmlDataTableHandler extends ComponentHandler {

    public CustomHtmlDataTableHandler(ComponentConfig config) {
        super( config );
    }
    
    protected MetaRuleset createMetaRuleset(Class type) {
        return super.createMetaRuleset(type).addRule( ActionSourceRule.Instance 
);
    }
    
    static final class ActionSourceRule extends MetaRule {
        
        private static final String ACTION_LISTENER_ATT_NAME = 
"toggleDetailActionListener";

        public final static Class[] ACTION_LISTENER_SIG = new Class[] { 
ActionEvent.class };

        final static class ActionListenerMapper extends Metadata {

            private final TagAttribute attr;

            public ActionListenerMapper(TagAttribute attr) {
                this.attr = attr;
            }

            public void applyMetadata(FaceletContext ctx, Object instance) {
                ((CustomHtmlDataTable) instance)
                        .setToggleDetailActionListener( new 
LegacyMethodBinding(this.attr
                                .getMethodExpression(ctx, null,
                                        ActionSourceRule.ACTION_LISTENER_SIG)));
            }

        }

        public final static ActionSourceRule Instance = new ActionSourceRule();

        public ActionSourceRule() {
            super();
        }

        public Metadata applyRule(String name, TagAttribute attribute,
                MetadataTarget meta) {
            if (meta.isTargetInstanceOf(CustomHtmlDataTable.class)) {
                
                if (ACTION_LISTENER_ATT_NAME.equals(name)) {
                    return new ActionListenerMapper(attribute);
                }
            }
            return null;
        }
    }

}


I hope this is basically the correct approach...

Cheers,
Martin



>  Use one of these technologies: 
> 
> 1) JBoss-Seam. Set the action to run in the pages.xml file. Example:
> 
>   <page view-id="/index.xhtml"
>     action="#{welcomeBean.onLoad}" />
> 
> 2) On-load from jsf-comp:
> http://jsf-comp.sourceforge.net/components/onload/index.html
> 
> 3) or use Shale (I have no experience with this one):
> http://shale.apache.org/shale-view/index.html
> 
> -Andrew
> 
> On 12/11/06, Martin Grotzke <[EMAIL PROTECTED]> wrote:
>         On Mon, 2006-12-11 at 10:29 -0500, Simon Lessard wrote:
>         > Hello Martin,
>         >
>         > Can you provide a mopre explicit example of the use case
>         please?
>         Sorry for the few words, if you think about a problem for
>         several days 
>         to you it seems just too clear ;)
>         
>         What I have is a datatable in a template with the detailStamp
>         facet:
>         
>         <table jsfc="t:dataTable"
>                 ...
>                 value="#{myBean.myModel}" 
>                 var="myItem"
>                 varDetailToggler="detailToggler">
>         
>                 ... some columns ...
>         
>                 <span jsfc="f:facet" name="detailStamp">
>                         <ui:include src=" itemdetails.xhtml">
>                                 <ui:param name="item"
>         value="#{myItem}"/>
>                         </ui:include>
>                 </span>
>         </table>
>         
>         The itemdetails.xhtml displays details to the item, e.g. it
>         iterates
>         over some detail options like the following:
>         
>         <ui:repeat var="option" value="#{item.myOptions}">
>                 #{option.description}
>         </ui:repeat> 
>         
>         So the the myBean.myModel.myOptions method is requested when
>         the detailStamp
>         is displayed for one item, this method is invoked when
>         rendering happens.
>         
>         When myBean.myModel.myOptions is invoked the first time, I do
>         some lazy 
>         initialization, this might cause errors...
>         
>         I do not see how I could do the processing in the invoke
>         application, because
>         the detailStamp is shown via HtmlDataTable.toggleDetail, which
>         is invoked
>         during invoke-application, but there's no possibility of
>         specifying a listener 
>         that is invoked when toggleDetail is invoked...
>         
>         I hope this clarifies the problem a little bit, if s.th. is
>         missing please
>         let me know!
>         
>         Thanx a lot,
>         cheers,
>         Martin
>         
>         
>         
>         > Why can't you do the processing in the invoke application
>         phase?
>         > Without more details, all I could suggest is to use a render
>         response
>         > phase listener and add your logic in the beforePhase
>         method. 
>         >
>         >
>         > Regards,
>         >
>         > ~ Simon
>         >
>         > On 12/11/06, Martin Grotzke <[EMAIL PROTECTED]>
>         wrote:
>         >         Hi all,
>         >
>         >         I have a case where I perform some logic during the
>         >         RENDER_RESPONSE
>         >         phase where an error might occurs and I want to
>         display some
>         >         error
>         >         message - which is unfortunately not displayed
>         directly. But 
>         >         with the
>         >         next request/response the error message is
>         displayed. I asume
>         >         that this
>         >         is the case because the h:messages component is
>         already
>         >         rendered - so 
>         >         the behavior should basically be correct.
>         >
>         >         Do you have any suggestions how to handle this?
>         >
>         >         The concrete case is when the details of a dataTable
>         (facet
>         >         detailStamp) 
>         >         are displayed - just comes into my mind to use a
>         >         CustomHtmlDataTable
>         >         component that overrides the toggleDetail method...
>         What do
>         >         you think?
>         >
>         >         Thanx in advance, 
>         >         cheers,
>         >         Martin
>         >
>         >
>         >
>         >
>         >
>         >
>         --
>         Martin Grotzke
>         http://www.javakaffee.de/blog/
>         
>         
> 
-- 
Martin Grotzke
http://www.javakaffee.de/blog/

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to