-
FEATURED COMPONENTS
First time here? Check out the FAQ!
1 | initial version | |
Just point out in stead of make it nested then workaround restrict this or prevent that, prevent the nested directly is another choice.
Another way is make the parent to keep the binding bean for BindingMacro child, please refer to the sample below.
In first case there are four macro component with binding with respect to the specified bean name, two of them are nested and the other two are not, all work fine.
In second case there are two macro component with binding, one is nested and the other is not, both work fine.
test with 5.0.8 or later:
consider multiple macro with dynamic bean name:
MacroComposer.java
package jtsptbo$v2;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.util.GenericForwardComposer;
public class MacroComposer extends GenericForwardComposer {
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
String beanName = ((MacroComp)comp.getParent().getParent()).getBeanName();
Executions.createComponentsDirectly("<label id=\"mc_label\" value=\"@{"+beanName+".time}\" />", null, comp, null);
}
}
Bean.java
package jtsptbo$v2;
import java.util.Date;
public class Bean {
String _entity;
public Bean (String entity) {
_entity = entity;
}
public String getTime() {
return _entity + " time: " + new Date(System.currentTimeMillis()).toString();
}
}
BindingMacro.java
package jtsptbo$v2;
import org.zkoss.zkplus.databind.AnnotateDataBinder;
public interface BindingMacro {
/**
* return whether this component has binding
*/
public boolean hasBinding();
/**
* put all binding to another binder
*/
public void delegateBinding(AnnotateDataBinder adb);
}
MacroComp.java
package jtsptbo$v2;
import org.zkoss.zk.ui.HtmlMacroComponent;
import org.zkoss.zkplus.databind.AnnotateDataBinder;
public class MacroComp extends HtmlMacroComponent implements BindingMacro {
Bean b;
String _beanName;
boolean _hasBinding = true;
public void afterCompose() {
super.afterCompose();
b = new Bean(_beanName);
AnnotateDataBinder binderOne = (AnnotateDataBinder)getFirstChild().getAttribute("binder");
binderOne.bindBean(_beanName, b);
binderOne.loadAll();
}
/**
* return whether this component has binding
*/
public boolean hasBinding() {
return _hasBinding;
}
/**
* put all binding to another binder
*/
public void delegateBinding(AnnotateDataBinder adb) {
adb.bindBean(_beanName, b);
getFirstChild().setAttribute("binder", null);
_hasBinding = false;
}
public void setBeanName(String beanName) {
_beanName = beanName;
}
public String getBeanName() {
return _beanName;
}
}
TestComposer.java
package jtsptbo$v2;
import java.util.*;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zkplus.databind.AnnotateDataBinder;
public class TestComposer extends GenericForwardComposer {
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
// get the binder of this composer
AnnotateDataBinder binderTwo = (AnnotateDataBinder)comp.getAttribute("binder");
List<Component> children = comp.getChildren();
for (Component c : children) {
if (c instanceof BindingMacro) {
// if the child is a BindingMacro and has binding,
// get binding from it
BindingMacro bc = (BindingMacro) c;
if (bc.hasBinding())
bc.delegateBinding(binderTwo);
}
}
binderTwo.bindBean("beanTwo", new Bean(" outer div"));
binderTwo.loadAll();
}
}
macrocomp.zul
<zk>
<window style="display: inline-block;" apply="org.zkoss.zkplus.databind.AnnotateDataBindingComposer">
<window id="mc_innerWin" apply="jtsptbo$v2.MacroComposer">
</window>
</window>
</zk>
index.zul
<?component name="macrocomp" macroURI="macrocomp.zul"
class="jtsptbo$v2.MacroComp"?>
<zk>
<div apply="org.zkoss.zkplus.databind.AnnotateDataBindingComposer,jtsptbo$v2.TestComposer">
<label id="windowLabel" value="@{beanTwo.time}" /><div></div>
<!-- There is another AnnotateDataBindingComposer
and bind another bean in macrocomp -->
<macrocomp beanName="firstMacro" /><div></div>
<macrocomp beanName="secondMacro" />
</div>
<macrocomp beanName="thirdMacro" /><div></div>
<macrocomp beanName="4thMacro" />
</zk>
allowed only one macro in nested:
Bean.java
package jtsptbo$v1;
import java.util.Date;
public class Bean {
public String getTime() {
return "time: " + new Date(System.currentTimeMillis()).toString();
}
}
BindingMacro.java
package jtsptbo$v1;
import org.zkoss.zkplus.databind.AnnotateDataBinder;
public interface BindingMacro {
/**
* return whether this component has binding
*/
public boolean hasBinding();
/**
* put all binding to another binder
*/
public void delegateBinding(AnnotateDataBinder adb);
}
MacroComp.java
package jtsptbo$v1;
import org.zkoss.zk.ui.HtmlMacroComponent;
import org.zkoss.zkplus.databind.AnnotateDataBinder;
public class MacroComp extends HtmlMacroComponent implements BindingMacro {
Bean b = new Bean();
boolean _hasBinding = true;
public void afterCompose() {
super.afterCompose();
AnnotateDataBinder binderOne = (AnnotateDataBinder)getFirstChild().getAttribute("binder");
binderOne.bindBean("bean", b);
getFirstChild().getFellow("mc_label");
binderOne.loadAll();
}
/**
* return whether this component has binding
*/
public boolean hasBinding() {
return _hasBinding;
}
/**
* put all binding to another binder
*/
public void delegateBinding(AnnotateDataBinder adb) {
adb.bindBean("bean", b);
getFirstChild().setAttribute("binder", null);
_hasBinding = false;
}
}
TestComposer.java
package jtsptbo$v1;
import java.util.*;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zkplus.databind.AnnotateDataBinder;
public class TestComposer extends GenericForwardComposer {
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
// get the binder of this composer
AnnotateDataBinder binderTwo = (AnnotateDataBinder)comp.getAttribute("binder");
List<Component> children = comp.getChildren();
for (Component c : children) {
if (c instanceof BindingMacro) {
// if the child is a BindingMacro and has binding,
// get binding from it
BindingMacro bc = (BindingMacro) c;
if (bc.hasBinding())
bc.delegateBinding(binderTwo);
}
}
binderTwo.bindBean("beanTwo", new Bean());
binderTwo.loadAll();
}
}
macrocomp.zul
<zk>
<window style="display: inline-block;" apply="org.zkoss.zkplus.databind.AnnotateDataBindingComposer">
<label id="mc_label" value="@{bean.time}" />
</window>
</zk>
index.zul
<?component name="macrocomp" macroURI="macrocomp.zul"
class="jtsptbo$v1.MacroComp"?>
<zk>
<div apply="org.zkoss.zkplus.databind.AnnotateDataBindingComposer,jtsptbo$v1.TestComposer">
<label id="windowLabel" value="@{beanTwo.time}" /><div></div>
<!-- There is another AnnotateDataBindingComposer
and bind another bean in macrocomp -->
<macrocomp />
</div>
<macrocomp />
</zk>
Regards, ben