Tabs and Databind

TOtte
93 2

Hi
I have multiple windows where I use <?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>. This was working very well so far.
Now I want to integrate my windows into one page, where each of the windows is included into a tabpanel.
If I define the AnnotateDataBinderInit in each .zul before the window definition, then I get an exception "page is already covered by another Data Binder. Cannot be covered by this Data Binder again". If I initialize the DataBinder in the page that contains the tabs, then the Databinding tries to access all the fields, even if I am only working in one of the tabs and therefore I also run into exceptions.

Is there a good way to overcome this problem?

Thank you

delete retag edit

3 Replies

TOtte
93 2

I am using ZK 5 if that matters for this problem.

The code of my main zul looks like this:

<zk>
<window title="Stammdatenpflege" border="normal">
<tabbox>
<tabs>
<tab id="herstellerTab" label="Hersteller Stammdatenpflege"></tab>
<tab id="StandortTab" label="Standorte Stammdatenpflege"></tab>
<tab label="Mandanten Stammdatenpflege"></tab>
</tabs>
<tabpanels>
<tabpanel><include src="HerstellerStammdatenpflege.zul"/></tabpanel>
<tabpanel><include src="StandortStammdatenpflege.zul"/></tabpanel>
<tabpanel></tabpanel>
</tabpanels>
</tabbox>
</window>
</zk>


There is no page definition right now, but I tried that, too.

Here is one of the pages that is supposed to be included in a tab.

<?page title="Stammdatenpflege - Hersteller" cacheable="false"
language="xul/html" zscriptLanguage="Java" contentType="text/html;charset=UTF-8"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>
<window id="win" title="Stammdatenpflege - Hersteller" border="normal" apply="controller.HerstellerController">
<listbox id="box" multiple="true" rows="10" model="@{win$composer.alleHersteller, load-after='add.onClick, delete.onClick, update.onClick, nummer_intbox.onChange, name_textbox.onChange'}" selectedItem="@{win$composer.current}">
<listitem id="item" self="@{each='hersteller'}" value="@{hersteller}">
<listcell> <intbox id="nummer_intbox" value="@{hersteller.nummer}"/></listcell>
<listcell> <textbox id="name_textbox" value="@{hersteller.name}" /></listcell>
<listcell>
<checkbox id="delete_checkbox" label="Löschen" />
</listcell>
</listitem>
</listbox>
<groupbox mold="3d">
<caption label="Hersteller" />
Nummer: <intbox id="nummer" cols="25" value="@{win$composer.current.nummer}"></intbox> Name: <textbox id="name" cols="25" value="@{win$composer.current.name}"></textbox>
<button id="update" label="Update" width="46px" height="24px"/>
<button id="delete" label="Delete" width="46px" height="24px"/>
</groupbox>
</window>


Somebody got an idea how to solve this problem? I tried to find an example where both Tabs and Databinding are used and the sources are available?

Thanks

robertpic71
1275 1

Hi,

Variant 1:
use absolute path's

Variant 2:
use relativ path

Check the API for the parameters for variant 1 + 2.

Variant 3:
Remove the XML-Tag and setup the binder inside the composer/controller.

..
AnnotateDataBinder binder;
...
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
binder = new AnnotateDataBinder(comp);
binder.bindBean("controller", this); // optional, enables smarter syntax in zul


+ you own/know the binder-instance - this makes it more easy to perform an extra load and/or extra save
+ you can register your own names for the binder (e.g. controller or model for the model-tier)
--> value="@{win\$composer.current.name}" becomes to value="@{controller.current.name}"
+ no path headache when the gui (vs. variant 1) is changing - every controller, owns his own binderinstance.

/Robert

TOtte
93 2

I implementet the 3rd variant and it works well. I didn't really understand yet what you mean by "You have the first load manually (binder.loadAll()) - but could prepare the data before the firstload." What could I do there?

Thanks again
Tobias

[hide preview]