English 中文(简体)
ZK: How to create component and register databinding
原标题:

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.

最佳回答

Unfortunately, the current DataBinder does NOT support dynamic binding yet (Have to wait Data Binding 2.0, hopefully will available in ZK 5.5).

The current DataBinder implementation will IGNORE all later added Bindings after first getXxx() or setXxx() call. In those methods, the init() method is called on demand and not called again if ever called. In the init() method, basically DataBinder scans through all the Bindings and construct an internal data structure and use those internal data structure afterward.(That is why the later added binding is not seen by the DataBinder)

Hope this clarify your issue.

问题回答

In zk 8, this could be achieved with the template mechanism and the @load and @bind features of the viewmodel concept: http://books.zkoss.org/zk-mvvm-book/8.0/data_binding/children_binding.html





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签