Macro Components and The ID Space

Like window, a macro component is an ID space owner. In other words, it is free to use whatever identifiers to identify components inside the page implementing a macro component (aka., child components of the macro component). They won't conflict with components defined in the same page with the macro component.

For example, assume we have a macro defined as follows.

<hbox>
    Username: <textbox id="who" value="${arg.who}"/>    
</hbox>

Then, the following codes work correctly.

<?component name="username" macroURI="/WEB-INF/macros/username.zul"?>
<zk>
    <username/>    
    <button id="who"/> <!-- no conflict because it is in a different ID space -->    
</zk>

However, the following codes don't work.

<?component name="username" macroURI="/WEB-INF/macros/username.zul"?>
<username id="who"/>

Why? Like any ID space owner, the macro component itself is in the same ID space with its child components. There are two alternative solutions:

1. Use a special prefix for the identifiers of child components of a macro component. For example, "mc_who" instead of "who".

    <hbox>
        Username: <textbox id="mc_who" value="${arg.who}"/>    
    </hbox>
    

    2. Use the window component to create an additional ID space.

      <window>
          <hbox>    
              Username: <textbox id="who" value="${arg.who}"/>        
          </hbox>    
      </window>
      

      The first solution is suggested, if applicable, due to the simplicity.

      Access Child Components From the Outside

      Like other ID space owner, you can access its child component by use of two getFellow method invocations or org.zkoss.zk.ui.Path.

      For example, assume you have a macro component whose ID is called "username", and then you can access the textbox as follows.

      comp.getFellow("username").getFellow("mc_who");
      new Path("/username/mc_who");
      

      Access Variables Defined in the Ancestors

      Macro components work as inline-expansion. Thus, like other components, a child component (of a macro component) can access any variable defined in the parent's ID space.

      For example, username's child component can access v directly.

      <zscript>
          String v = "something";    
      </zscript>
      <username/>
      

      However, it is not recommended to utilize such visibility because it might limit where a macro can be used.

      Change macroURI At the Runtime

      You can change the macro URI dynamically as follows.

      <username id="ua"/>
      <button onClick="ua.setMacroURI(&quot;another.zul&quot;)"/>