2010-07-28 2 views
1

안녕하세요, 웹 응용 프로그램을 개발하는 ZK framework을 사용하고ZK : 구성 요소를 만들고

데이터 바인딩 등록하는 방법. 구성 요소에 데이터 바인딩을 사용하여 값을 설정하고 가져옵니다. 소스 ZUL 파일과 페이지의 컨트롤러에서 doAfterCompose 메소드에서 데이터 바인딩을 등록 할 수 있습니다. 이 메소드는 페이지 작성 중에 호출됩니다. 하지만 이제는 새 구성 요소를 추가해야하며 기존 및 작성 페이지에 데이터 바인딩이 필요합니다. 내가 만드는 구성 요소를 만드는 방법은 간단하지만 데이터 바인딩을 등록하는 데 문제가 있습니다. 프레임 워크에서 알 수없는 데이터 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); 
     } 

    } 
} 

는 응용 프로그램이 잘 작동합니다. 버튼에 onClick 이벤트가 생성되면 새로운 텍스트 박스가 생성되고 그 값은 올바른 속성에 바인딩됩니다. 하지만 지금, 만약 내가 ZUL 파일에있는 텍스트 박스 컴포넌트를 주석 처리한다면

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

그때 그것은 멈춘다. 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 파일에서 빈을 사용하지 않고 새로운 컴포넌트를 생성하고 데이터 바인딩을 추가 할 수 있어야합니다. 컨트롤러에서 등록 할 수 있어야합니다. 도와 줄수있으세요? 나는 정말로 감사 할 것이다.

답변

1

불행히도 현재 데이터 바인더는 동적 바인딩을 아직 지원하지 않습니다 (데이터 바인딩 2.0을 기다려야합니다. ZK 5.5에서 사용 가능할 것입니다).

현재 DataBinder 구현은 첫 번째 getXxx() 또는 setXxx() 호출 이후에 나중에 모두 추가 된 Binding을 무시합니다. 이러한 메소드에서 init() 메소드는 요청시 호출되며 호출 될 경우 다시 호출되지 않습니다. init() 메서드에서 기본적으로 DataBinder는 모든 Binding을 검사하고 내부 데이터 구조를 구성한 다음 나중에 이러한 내부 데이터 구조를 사용합니다 (즉, 나중에 추가 된 바인딩이 DataBinder에 표시되지 않습니다).

희망 사항 너의 문제.

+0

고마워. 내가 생각했던 것을 확인해 줬어. 바인딩 트리는 페이지 구성 중에 작성되었으며 이후에는 변경 될 수없는 것으로 나타났습니다. 기존의 내부 구조에 일부 데이터 bean을 추가하는 데 많은 시간을 들였지만 아무 것도 성공하지 못했습니다. 우리는 ZK 프레임 워크의 일부 (바인딩의 일부 임)를 다시 작성했지만이 문제는 아직 해결되지 않았습니다. 다른 해결책을 찾아야 해. 다시 한번 고마워. – Gaim