Page Initialization"

From Documentation
m
m ((via JWB))
 
(25 intermediate revisions by 7 users not shown)
Line 1: Line 1:
 
{{ZKDevelopersReferencePageHeader}}
 
{{ZKDevelopersReferencePageHeader}}
  
Sometimes it is helpful to run some code before ZK Loader instantiates any component. For example, check if the user ha the authority to access, initialize some data, or prepare some variables for EL expressions<ref>The preparation of variables for EL expression is generally better to be done in the constructor of <javadoc type="interface">org.zkoss.xel.VariableResolver</javadoc> (and specified with [[ZUML Reference/ZUML/Processing Instructions/variable-resolver|the variable-resolver directive]].</ref>.
+
__TOC__
  
This can be done easily by implementing <javadoc type="interface">org.zkoss.zk.ui.util.Initiator</javadoc>, and then specifying it with [[ZUML Reference/ZUML/Processing Instructions/init|the init directive]].
+
Sometimes it is helpful to run some code before ZK Loader instantiates any component. For example, check if the user has the authority to access, initialize some data, or prepare some variables for EL expressions.
 +
 
 +
This can be done easily by implementing <javadoc type="interface">org.zkoss.zk.ui.util.Initiator</javadoc>/<javadoc type="interface">org.zkoss.zk.ui.util.InitiatorExt</javadoc>, and then specifying it with [[ZUML Reference/ZUML/Processing Instructions/init|the init directive]].
  
 
<source lang="xml">
 
<source lang="xml">
Line 9: Line 11:
 
</source>
 
</source>
  
A typical use of the init directive is to specify [[ZK Developer's Reference/Data Binding|a data binder]], as shown below.
 
  
<source>
+
=Initiator and EL=
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>
+
To prepare a variable for EL expression in an initiator, you could store the variable in the page's attributes.
 +
 
 +
<blockquote>
 +
----
 +
'''Notice''' that the provision of variables for EL expression is generally better to be done with <javadoc type="interface">org.zkoss.xel.VariableResolver</javadoc> (and then specified it with [[ZUML Reference/ZUML/Processing Instructions/variable-resolver|the variable-resolver directive]]).
 +
</blockquote>
 +
 
 +
For example, suppose we have a class, <code>CustomerManager</code>, that can be used to load all customers, then we could prepare a variable to store all customers as follows.
 +
 
 +
<source lang="java" highlight='6' >
 +
public class AllCustomerFinder implements Initiator, InitiatorExt {
 +
 
 +
    @Override
 +
    public void doInit(Page page, Map args) throws Exception {
 +
        String name = (String)args.get("name");
 +
        page.setAttribute(name != null ? name: "customers", CustomerManager.findAll());
 +
    }
 +
    ...
 +
}
 +
</source>
 +
 
 +
Then, we could use the initiator in a ZUML document as follows.
 +
 
 +
<source lang="xml" highlight='1,9'>
 +
<?init class="my.AllCustomerFinder" name="customers"?>
 +
 
 +
<listbox id="personList" width="800px" rows="5">
 +
    <listhead>
 +
        <listheader label="Name"/>
 +
        <listheader label="Surname"/>
 +
        <listheader label="Due Amount"/>
 +
    </listhead>
 +
    <listitem value="${each.id}" forEach="${pageScope.customers}">
 +
        <listcell label="${each.name}"/>
 +
        <listcell label="${each.surname}"/>
 +
        <listcell label="${each.due}"/>
 +
    </listitem>
 +
</listbox>
 +
</source>
 +
 
 +
= System-level Initiator =
 +
{{versionSince | 5.0.7}}
 +
 
 +
If you have an initiator that shall be invoked for each page, you could register a system-level initiator, rather than specifying it on every page.
 +
 
 +
It could be done by specifying the initiator you implemented in <code>WEB-INF/zk.xml</code> as follows. For more information, please refer to [[ZK Configuration Reference/zk.xml/The listener Element|ZK Configuration Reference]].
 +
 
 +
<source lang="xml">
 +
<listener>
 +
    <listener-class>foo.MyInitiator</listener-class>
 +
</listener>
 
</source>
 
</source>
  
The data binder will parse all annotations and bind the data according to the annotations, after all components in a ZUML document is instantiated.
+
Once specified, an instance of the given class will be instantiated for each page (<javadoc type="interface">org.zkoss.zk.ui.Page</javadoc>), and then its method will be called as if they are specified in the page ([[ZUML Reference/ZUML/Processing Instructions/init|the init directive]]).
 +
 
 +
=Exception Handling=
 +
The initiator can be used to handle the exception when ZK Loader renders a page by implementing <javadoc type="interface" method="doCatch(java.lang.Throwable)">org.zkoss.zk.ui.util.InitiatorExt</javadoc>
  
 
<blockquote>
 
<blockquote>
 
----
 
----
<references/>
+
'''Notice''' that it does not cover the exception thrown in an event listener, which could be handled by the use of <javadoc type="interface">org.zkoss.zk.ui.util.ExecutionCleanup</javadoc>.
 
</blockquote>
 
</blockquote>
 +
 +
<source lang="java" >
 +
import org.zkoss.zk.ui.Page;
 +
import org.zkoss.zk.ui.util.Initiator;
 +
import org.zkoss.zk.ui.util.InitiatorExt;
 +
 +
public class ErrorHandler implements Initiator, InitiatorExt {
 +
    public void doInit(Page page, Map args) throws Exception {
 +
    }
 +
    public void doAfterCompose(Page page) throws Exception { //nothing to do
 +
    }
 +
    public boolean doCatch(Throwable ex) throws Exception {
 +
        //handle exception here
 +
        return shallIgnore(ex); //return true if the exception is safe to ignore
 +
    }
 +
    public void doFinally() throws Exception {
 +
        //the finally cleanup
 +
    }
 +
}
 +
</source>
 +
 +
 +
  
 
=Version History=
 
=Version History=
{{LastUpdated}}
+
 
{| border='1px' | width="100%"
+
{| class='wikitable' | width="100%"
 
! Version !! Date !! Content
 
! Version !! Date !! Content
 
|-
 
|-
| &nbsp;
+
| 5.0.7
| &nbsp;
+
| April 2011
| &nbsp;
+
| The system-level initiator was introduced.
 
|}
 
|}
  
 
{{ZKDevelopersReferencePageFooter}}
 
{{ZKDevelopersReferencePageFooter}}

Latest revision as of 07:38, 8 July 2022


Page Initialization


Sometimes it is helpful to run some code before ZK Loader instantiates any component. For example, check if the user has the authority to access, initialize some data, or prepare some variables for EL expressions.

This can be done easily by implementing Initiator/InitiatorExt, and then specifying it with the init directive.

<?init class="com.foo.MyInitial"?>


Initiator and EL

To prepare a variable for EL expression in an initiator, you could store the variable in the page's attributes.


Notice that the provision of variables for EL expression is generally better to be done with VariableResolver (and then specified it with the variable-resolver directive).

For example, suppose we have a class, CustomerManager, that can be used to load all customers, then we could prepare a variable to store all customers as follows.

public class AllCustomerFinder implements Initiator, InitiatorExt {

    @Override
    public void doInit(Page page, Map args) throws Exception {
        String name = (String)args.get("name");
        page.setAttribute(name != null ? name: "customers", CustomerManager.findAll());
    }
    ...
}

Then, we could use the initiator in a ZUML document as follows.

 <?init class="my.AllCustomerFinder" name="customers"?>

 <listbox id="personList" width="800px" rows="5">
     <listhead>
         <listheader label="Name"/>
         <listheader label="Surname"/>
         <listheader label="Due Amount"/>
     </listhead>
     <listitem value="${each.id}" forEach="${pageScope.customers}">
         <listcell label="${each.name}"/>
         <listcell label="${each.surname}"/>
         <listcell label="${each.due}"/>
     </listitem>
 </listbox>

System-level Initiator

Since 5.0.7

If you have an initiator that shall be invoked for each page, you could register a system-level initiator, rather than specifying it on every page.

It could be done by specifying the initiator you implemented in WEB-INF/zk.xml as follows. For more information, please refer to ZK Configuration Reference.

<listener>
    <listener-class>foo.MyInitiator</listener-class>
</listener>

Once specified, an instance of the given class will be instantiated for each page (Page), and then its method will be called as if they are specified in the page (the init directive).

Exception Handling

The initiator can be used to handle the exception when ZK Loader renders a page by implementing InitiatorExt.doCatch(Throwable)


Notice that it does not cover the exception thrown in an event listener, which could be handled by the use of ExecutionCleanup.

import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.util.Initiator;
import org.zkoss.zk.ui.util.InitiatorExt;

public class ErrorHandler implements Initiator, InitiatorExt {
    public void doInit(Page page, Map args) throws Exception {
    }
    public void doAfterCompose(Page page) throws Exception { //nothing to do
    }
    public boolean doCatch(Throwable ex) throws Exception {
        //handle exception here
        return shallIgnore(ex); //return true if the exception is safe to ignore
    }
    public void doFinally() throws Exception {
        //the finally cleanup
    }
}



Version History

Version Date Content
5.0.7 April 2011 The system-level initiator was introduced.



Last Update : 2022/07/08

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.