ЗК: Как создать компонент и зарегистрировать привязку данных - PullRequest
1 голос
/ 28 июля 2010

Привет,

Я использую ZK framework для разработки веб-приложений.Я использую привязку данных на компонентах, чтобы установить и получить значения.Я могу зарегистрировать привязку данных в исходном файле ZUL, а также в методе doAfterCompose в контроллере страницы.Этот метод вызывается при компоновке страницы.Но теперь мне нужно добавить новый компонент и привязать его к существующей и составленной странице.Как создать компонент, я знаю, это просто, но у меня есть проблема с регистрацией привязки данных.Framework выдает исключение, что я использую неизвестный компонент данных.

Существует простой код, который должен работать, но это не так.Этот 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 );
        }

    }
}

Если я запускаю эти два файла, приложение работает нормально.При событии onClick при нажатии кнопки создается новое текстовое поле и его значение привязывается к нужному свойству.Но теперь, если я комментирую компонент текстового поля в файле ZUL

        <!--textbox id="txt1" value="@{ctl.bindingValue}"/-->

, он перестает работать.Теперь возникло исключение

Не удается найти указанное выражение bean-компонента привязки: 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)

И это проблема.Мне нужно иметь возможность создать новый компонент и добавить его привязку данных без использования bean-компонента в файле ZUL.Мне нужно иметь возможность зарегистрировать его с контроллера.Не могли бы вы мне помочь?Я буду очень благодарен.

1 Ответ

1 голос
/ 28 июля 2010

К сожалению, текущий DataBinder пока не поддерживает динамическое связывание (придется подождать привязку данных 2.0, надеюсь, будет доступно в ZK 5.5).

Текущая реализация DataBinder будет игнорировать все последующие добавленные привязки после первого getXxx () или setXxx () вызов.В этих методах метод init () вызывается по требованию и не вызывается снова, если когда-либо вызывался.В методе init () в основном DataBinder просматривает все привязки и создает внутреннюю структуру данных, а затем использует эту внутреннюю структуру данных (вот почему позднее добавленная привязка не видна DataBinder)

Надеждаэто прояснит вашу проблему.

...