0

app composition + browser refresh

asked 2008-12-17 01:13:57 +0800

caclark gravatar image caclark
1753 2 5
http://clarktrips.intltwi...

I'm still new at ZK, but have been working on a prototype. I have an app that requires login. I have put together a simple login page in addition to my main app page. Both use the "apply" attribute with a GenericForwardComposer backing them.

In the main app .zul, I have a window that is initially NOT visible. I have a macro component defined for the login window and have an instance of it defined as a sibling to my main app window. The login window's controller handles the click of the login button and uses a Spring-based service to validate the employee. If the id + password are valid, I post an event with the domain object as the value. I want to catch the "onLogin" event in my main app controller, so I thought I'd hook it in the onCreate of that controller with this code:

    public void onCreate(Event event)
        throws Exception
    {
        logger.debug( className + "::onCreate: starting " + event.getName() ) ;

        Window win = (Window)page.getFellow("lw").getFellow("win") ;
        win.addEventListener( "onLogin", this ) ;
    }

The problem that I'm having is one that I discovered by accident. If I start Tomcat fresh and load the app the page.getFellow("lw").getFellow("win") works just fine. But, if I press the browser refresh button, the onCreate is run again but most of the time the page.getFellow("lw") fails saying it can't find fellow "lw".

Both controllers are Spring beans and are scoped as session. The have services injected by Spring.

At this point, I'm not sure if I'm doing something wrong or if this is a bug. Is there a better way to hook my custom event?

I've experimented using createComponent( ... ) in the app controller onCreate(), too, but with as bad of a result. I hooked the onLogin, but when it runs and I try to make the main app visible, it pukes because the main app's desktop is null.


So, I'm stuck at this point and would appreciate any input.

Thanks,
Cary


Here's the code for the login window:

<zk>
    <?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
    <window id="win" title="Login" border="normal" width="350px" apply="${loginController}" 
            position="center" action="onshow: anima.moveDown(#{win}, 2000);" >
        <groupbox>
            <caption>Login</caption>
            <grid>
                <rows>
                    <row>User: 
                        <textbox id="userId" onOK="password.focus( )" onCreate="self.focus()" />
                    </row>
                    <row>Password: 
                        <textbox id="password" forward="onOK=loginButton.onClick" />
                    </row>
                    <row spans="2">
                        <hbox>
                            <button id="loginButton" label="Login" />
                        </hbox>
                    </row>
                </rows>
            </grid>
        </groupbox>
    </window>
</zk>

and the relevent part of the main app:

<zk>
    <?page id="vehicleRequestAppPage"?>
    <?component name="loginWindow" macroURI="/common/zul/loginWindow.zul" ?>

    <?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
    <?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="vehicleRequestApp" ?>

    <window id="vehicleRequestApp" width="100%" contentSclass="vehicleRequestApp" height="100%" 
            apply="${vehicleRequestAppController}" visible="false">

        <!--
               ...  various components ...
        -->
    </window>

    <loginWindow id="lw" visible="false" />
</zk>

my onLogin handler:

    
    public void onLogin(Event event)
        throws Exception
    {
        logger.debug( className + "::onLogin: starting " + event.getName() ) ;
        user = (Employee)event.getData() ;

        //  I've tried using both references to the main app window...they're the same
        //Window appWin = (Window)this.page.getFellow( "vehicleRequestApp" ) ;
        Window appWin = (Window)this.self ;
        appWin.setVisible( true ) ;

        //  I've also tried
        appWin.doEmbedded( ) ;
    }

delete flag offensive retag edit

1 Reply

Sort by ยป oldest newest

answered 2008-12-18 04:47:31 +0800

robertlee gravatar image robertlee
561

Under the component creation phase, i quote the dev guide:

Note: an developer can perform some application-specific initialization by listening to the onCreate event or implementing AfterCompose. AfterCompose is called in the Component Creation Phase, while the onCreate event is handled by an event listener.

An event listener is free to suspend and resume the execution (such as creating modal dialogs), while AfterCompose is a bit faster since no need to fork another thread.

So, do you want to try implement the AfterCompose method instead?

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2008-12-17 01:13:57 +0800

Seen: 413 times

Last updated: Dec 18 '08

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More