Include"

From Documentation
Line 98: Line 98:
  
 
===Differences to the Instance Mode===
 
===Differences to the Instance Mode===
Here is a list of differences between the <tt>defer</tt> and <tt>instant</tt> modes if a ZUML document is included.
+
Here is a list of differences between the <tt>defer</tt> and <tt>instant</tt> modes if a ZUML document is included (directly or indirectly going through another, say, JSP page) to contain the components defined in the included ZUML document.
  
* In the <tt>defer</tt> mode, a <javadoc type="interface">org.zkoss.zk.ui.Page</javadoc> instance will be created.
+
* In the <tt>defer</tt> mode, an instance of <javadoc type="interface">org.zkoss.zk.ui.Page</javadoc> will be created.
 
* In the <tt>defer</tt> mode, the instantiated components become the root of the <javadoc type="interface">org.zkoss.zk.ui.Page</javadoc> instance. The <tt>include</tt> component itself has no child component at all.
 
* In the <tt>defer</tt> mode, the instantiated components become the root of the <javadoc type="interface">org.zkoss.zk.ui.Page</javadoc> instance. The <tt>include</tt> component itself has no child component at all.
 
* In the <tt>defer</tt> mode, the page is included when the <tt>include</tt> component is rendered. Thus, the <javadoc type="interface">org.zkoss.zk.ui.Page</javadoc> instance (and its content) is not available when loading the ZUML document that the <tt>include</tt> component belongs to. It means you cannot access any of its content until receiving an AU request from the client.
 
* In the <tt>defer</tt> mode, the page is included when the <tt>include</tt> component is rendered. Thus, the <javadoc type="interface">org.zkoss.zk.ui.Page</javadoc> instance (and its content) is not available when loading the ZUML document that the <tt>include</tt> component belongs to. It means you cannot access any of its content until receiving an AU request from the client.

Revision as of 04:53, 9 December 2010

Include

Employment/Purpose

The include component is used to include the output generated by another servlet. The servlet could be anything including JSF, JSP and even another ZUML page.

<window title="include demo" border="normal" width="300px">
	Hello, World!
	<include src="/userguide/misc/includedHello.zul" />
	<include src="/html/frag.html?some=any" />
	<include src="mypage" argument="${anyValue}" other="${anotherValue}" />
</window>

Like all other properties, you could dynamically change the src attribute to include the output from a different servlet at the run time.

If the included output is another ZUML, developers are allowed to access components in the included page as if they are part of the containing page.

If the include component is used to include a ZUML page, the included page will become part of the desktop. However, the included page is not visible until the request is processed completely. In other words, it is visible only in the following events, triggered by user or timer.

The reason is that the include component includes a page as late as the Rendering phase. On the other hand, zscript takes place at the Component Creation phase, and onCreate takes place at the Event Processing Phase. They both execute before the inclusion.

Example

<window title="include demo" border="normal" width="300px">
	Hello, World!
	<include src="/userguide/misc/includedHello.zul" />
	<include src="/html/frag.html?some=any" />
	<include src="mypage" argument="${anyValue}" other="${anotherValue}" />
</window>

Modes

There are two ways to include another ZUML document: instant and defer. It is controlled by the property called mode (Include.setMode(String)). By default, it is auto, i.e., the real mode is decided automatically as described below.

Auto

The auto mode (default) decides the mode based the page to include. If the page (Include.setSrc(String)) is ended with the extension named .zul or .zhtml, the <ttinstant mode is assumed. Otherwise, the defer mode is assumed. If it is not the case (such as your ZUML page's extension is not any of them), you could specify the mode explicitly.

Notice that if a query string is specified, the defer mode is assumed, too, since the instance mode does not support the query string.

The code below demonstrates how to use the auto mode:

<window title="demo" border="normal">
	<include mode="auto" src="another.zul" />
</window>

Instant

In the instant mode, the include component loads the page by use of Execution.createComponents(String, Component, Map). It means that the components defined in the included page are instantiated instantly and added as children of the include component.

Unlike the defer mode, no additional Page instance is created.

The code below demonstrates how to use the instant mode:

<window title="demo" border="normal">
	<include mode="instant" src="include.zul" />
</window>

Notice the include component itself is a ID space owner, so there is no issue of ID conflicts. But, it also means you have to use Path or other techniques to retrieve the child components.

Pass Values to the Included Page

you can pass values through Include.setDynamicProperty(String, Object). Unlike the defer mode, the query string is not supported in the instant mode.

For example:

 <include src="mypage" some="something" another="${expr}"/>

Then, you could retrieve the values by use the arg object as described in the Load ZUML in Java section.


In the defer mode, the values have to be retrieved by the requestScope object.

Defer

In the defer mode, the include component includes the page by going through the Servlet container(the include method of javax.servlet.RequestDispatcher). Thus, it is OK to include any kind of pages, not limited to ZUML documents.

<window title="demo" border="normal">
	<include mode="defer" src="include.zul" />
</window>

Differences to the Instance Mode

Here is a list of differences between the defer and instant modes if a ZUML document is included (directly or indirectly going through another, say, JSP page) to contain the components defined in the included ZUML document.

  • In the defer mode, an instance of Page will be created.
  • In the defer mode, the instantiated components become the root of the Page instance. The include component itself has no child component at all.
  • In the defer mode, the page is included when the include component is rendered. Thus, the Page instance (and its content) is not available when loading the ZUML document that the include component belongs to. It means you cannot access any of its content until receiving an AU request from the client.

Pass Values to the Included Page

There are two ways to pass values to the included page in the defer mode. First, you can pass them with the query string.

 <include mode="defer" src="mypage?some=something"/>

Then, in the included page, you can access them with Execution.getParameter(String) or the javax.servlet.ServletRequest interface. In EL expressions (of the included page), you can use the param object or the paramValues object to access them.

 ${param.some}

Notice that you can only pass String-typed values with the query string. Alternatively, we can pass any kind of values with the so-called dynamic properties by use of Include.setDynamicProperty(String, Object) or, in ZUL, a dynamic property as follows:

<include mode="defer" src="mypage" some="something" another="${expr}"/>

With the dynamic properties, you can pass non-String-typed values. In the included page, you can access them with Execution.getAttribute(String) or the javax.servlet.ServletRequest interface. In EL expressions (of the included page), you can use the requestScope object to access them.

 ${requestScope.some}

Include the Same Page Twice

With the include component, you could include any page multiple times no matter it is in the instant or defer mode. For example,

<include src="/mypage.zul"/>
<include src="/mypage.zul"/>

However, if you are using the defer mode and want to access the component inside of them, you have to assign a unique identifier of the page being included. Here is what you can do.

<include mode="defer" src="/mypage.zul?pageId=first"/>
<include mode="defer" src="/mypage.zul?pageId=second"/>

In additions, in the page being include, i.e., mypage.zul in this example, you have to write

<?page id="${param.pageId}"?>

Then, you could access their component by use of Path as follows.

Path.getComponent('//first/textbox/'); 
Path.getComponent('//second/textbox/');

Notice that, in the defer mode, components are created as late as rendering the include component, so you could access them only in the event listener serving AU requests (aka., Ajax).

Backward Compatibility

For versions prior to 5.0, the defer mode is the default. If you prefer to keep using the defer mode, you could specify a library property called org.zkoss.zul.include.mode as follows.

<library-property>
    <name>org.zkoss.zul.include.mode</name>
     <value>defer</value>
</library-property>

Refresh Included Pages

First, use the include component with either the instant or defer mode to include whatever page you want (ZUML, JSP, JSF or whatever) inside a ZK document. Second, you can dynamically change it by changing the src property (Include.setSrc(String).

For example, the following code would change the included page from hello.zul to byebye.zul, when an end user press the Bye! button.

<include id="inner" src="hello.zul"/>
<button label="Bye!" onClick='inner.src = "byebye.zul"'/>

If you want to reload the same page (and not to change to another page), you have to set the src property to null first; then set it back to what it was. Because ZK optimizes operations, setting the same value to the same property would be deemed to do nothing.

For example, the following code would refresh the hello.zul page when an end user press the Reload button.

<include id="inner" src="hello.zul"/>
<button id="reload" label="Reload" onClick="String tmp=inner.src; inner.src=null; inner.src=tmp;"/>

Another way to reload is to invalidate the "include" component by use of Component.invalidate() as follows.

<include id="inner" src="hello.zul"/>
<button id="reload" label="Reload" onClick="inner.invalidate();"/>

Notice that Component.invalidate() will cause the included page to be reloaded in both the instance and defer mode.

Supported Events

Name
Event Type
None None

Supported Children

*NONE

Use Cases

Version Description Example Location
     

Version History

Last Update : 2010/12/09


Version Date Content
5.0.0 January 2010 The mode is default to auto (rather than defer). You could configure the default mode to defer by specifying a library property called org.zkoss.zul.include.mode in WEB-INF/zk.xml.



Last Update : 2010/12/09

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