Hi,
I am using ZK framework to develop web applications. I am using databinding on components to set and get values. I can register databinding in source ZUL file and also in the method doAfterCompose in page s controller. This method is called during page composition. But now I have to add a new component and it s databinding into existing and composed page. How to create component I know, it is simple but I have a problem to register databinding. Framework throws the exception that I am using unknown data bean.
There is a simple code which should work but it doesn t. This ZUL file describes simple page layout and controller catches events etc. There are used annotations ZkModel and ZkEvents. These annotations aren t part of the framework, they are our enhancement. ZkModel publishes the variable to ZUL file so it is accessible from ZUL file using databinding. ZkEvent registers events on the components and invokes these methods on events. These enhancement is working so there is not the problem.
ZUL file (test.zul):
<?xml version="1.0" encoding="UTF-8"?>
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<?init class="cz.datalite.zk.databinder.DLDataBinderInit" root="winTest" validator="${validator}"?>
<!-- template -->
<?init class="org.zkoss.zk.ui.util.Composition" arg0="/includes/template.zul"?>
<?page title="Test page"?>
<zk xmlns="http://www.zkoss.org/2005/zul">
<window id="winTest" self="@{define(content)}" height="100%" apply="${testController}">
<button label="OK" id="btn"/>
<label id="lab" value="text"/>
<textbox id="txt1" value="@{ctl.bindingValue}"/>
</window>
</zk>
TestController.java:
package cz.datalite.bpej.evidence;
import cz.datalite.stereotype.Controller;
import cz.datalite.zk.annotation.ZkEvent;
import cz.datalite.zk.annotation.ZkModel;
import cz.datalite.zk.components.textbox.DLTextbox;
import cz.datalite.zk.composer.DLComposer;
import java.util.HashMap;
import java.util.Map;
import org.zkoss.zk.ui.Component;
import org.zkoss.zkplus.databind.Binding;
import org.zkoss.zkplus.databind.DataBinder;
import org.zkoss.zul.impl.XulElement;
@Controller // this class serves as a controller
public class TestController extends DLComposer {
@ZkModel // this property is published and accessible from ZUL file
String bindingValue = "there is binding text";
@ZkEvent( id = "btn" ) // this methods is invoked on "onClick" event on component "btn"
public void onOk() throws Exception {
DLTextbox textbox = new DLTextbox();
textbox.setParent( self );
setValueAnnotation( textbox, "value", "ctl.bindingValue" );
}
/**
* Sets the component s annotation to specific value
* (call eg. setValueAnnotation(comp, "model", "aaa") is corresponding to model="@{aaa}")
* @param comp defined component
* @param propName name of property
* @param annot annotation
*/
private void setValueAnnotation( XulElement comp, String propName, String annot ) {
DataBinder binder = ( DataBinder ) comp.getVariable( "binder", false );
// adds new binding
Map attrs = new HashMap();
attrs.put( "value", annot );
binder.addBinding( comp, propName, annot );
// if the first bean is fellow then register it ( if it hasn t been used yet then it is not registered. )
String bean = annot;
if ( bean.contains( "." ) ) {
bean = bean.split( "\." )[0];
}
Component fellowBean = comp.getFellowIfAny( bean );
if ( fellowBean != null ) {
binder.bindBean( bean, fellowBean );
}
// load components value
Binding bind = (( DataBinder ) comp.getVariable( "binder", false )).getBinding( comp, propName );
if ( bind != null ) {
bind.loadAttribute( comp );
}
}
}
If I run these two files the application works fine. On onClick event on button is created new textbox and its value is bind to the right property. But now, if I comment textbox component in ZUL file
<!--textbox id="txt1" value="@{ctl.bindingValue}"/-->
then it stops working. Now there is thrown exception
Cannot find the specified databind bean expression:ctl.bindingValue
org.zkoss.zkplus.databind.DataBinder(DataBinder.java#myGetBeanWithExpression:1004) org.zkoss.zkplus.databind.DataBinder(DataBinder.java#getBeanAndRegisterBeanSameNodes:988) org.zkoss.zkplus.databind.Binding(Binding.java#loadAttribute:413) cz.datalite.bpej.evidence.TestController(TestController.java#setValueAnnotation:58) cz.datalite.bpej.evidence.TestController(TestController.java#onOk:25)
And that is the problem. I need to be able to create a new component and add its databinding without using the bean in ZUL file. I need to be able to register it from the controller. Can you help me, please? I ll be really grateful.