やあ、
私はZKフレームワークを使用してWebアプリケーションを開発しています。コンポーネントでデータバインディングを使用して値を設定および取得しています。ソースZULファイルとページのコントローラーのメソッドdoAfterComposeにデータバインディングを登録できます。このメソッドは、ページ作成中に呼び出されます。しかし今、私は新しいコンポーネントを追加する必要があり、それは既存の構成されたページへのデータバインディングです。私が知っているコンポーネントの作成方法は簡単ですが、データバインディングの登録に問題があります。Frameworkは、不明なデータBeanを使用しているという例外をスローします。
動作するはずの単純なコードがありますが、動作しません。このZULファイルは、単純なページレイアウトとコントローラーキャッチイベントなどを記述します。使用されるアノテーションZkModelとZkEventsがあります。これらのアノテーションはフレームワークの一部ではなく、私たちの拡張機能です。ZkModelは変数をZULファイルに公開するため、データバインディングを使用してZULファイルからアクセスできます。ZkEventは、コンポーネントにイベントを登録し、イベントに対してこれらのメソッドを呼び出します。これらの拡張機能は機能しているため、問題はありません。
ZULファイル(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 );
}
}
}
これらの2つのファイルを実行すると、アプリケーションは正常に動作します。onClickイベントのonボタンは新しいテキストボックスを作成し、その値は適切なプロパティにバインドされます。しかし今、ZULファイルのテキストボックスコンポーネントにコメントすると
<!--textbox id="txt1" value="@{ctl.bindingValue}"/-->
その後、動作を停止します。今、スローされた例外があります
指定されたdatabindBean式が見つかりません: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)
そしてそれが問題です。ZULファイルのBeanを使用せずに、新しいコンポーネントを作成してそのデータバインディングを追加できるようにする必要があります。コントローラから登録できるようにする必要があります。手伝ってくれませんか。本当にありがたいです。