2009-01-12 75 views
0

我遇到了facelets中自定义组件的问题。页面首次被渲染时,属性在组件类上正确设置。但是,当提交表单时,属性不会被设置。Facelets自定义组件在提交后未设置属性

这是我用来测试这个的类。

public class TestEcho extends UIData 
{ 
    /** Logger. */ 
    private static Log log = LogFactory.getLog(TestEcho.class); 

    private String msg; 

    public TestEcho() 
    { 
     log.debug("Constructor."); 
    } 

    public void encodeEnd(FacesContext context) throws IOException 
    { 
     ResponseWriter writer = context.getResponseWriter(); 
     writer.startElement("div", this); 
     writer.writeText("The value of msg is '" + msg + "'.", null); 
     writer.endElement("div"); 
    } 

    public void setMsg(String msg) 
    { 
     log.debug("Setting msg to '" + msg + "'."); 
     this.msg = msg; 
    } 
} 

该组件在这个.xhtml页面中使用。

<h:form> 
    <v:testEcho msg="hello" /> 
    <h:commandButton action="#{PictureManager.trigger}" value="Click" /> 
</h:form> 

页面首次呈现时,组件呈现以下html代码。

<div>The value of msg is 'hello'.</div> 

当按钮被点击时,它呈现这个。

<div>The value of msg is 'null'.</div> 

从日志中,您可以看到组件再次构造,但未设置该属性。

13:23:42,955 DEBUG [TestEcho] Constructor. 
13:23:42,955 DEBUG [TestEcho] Setting msg to 'hello'. 
----- Button was pressed here ----- 
13:25:48,988 DEBUG [TestEcho] Constructor. 
13:25:49,144 DEBUG [PictureManager] Button pressed. 

据我了解,小面确实属性组件的所有线路,所以我并不需要一个标签类,但我不明白为什么会属性正确地在第一时间进行设置,但不第二次。

回答

1

您必须通过覆盖saveStaterestoreState方法来保存您的状态。

所以,saveState和必须返回一个Serializable对象(例如一个JavaBean或对象[]数组)中MSG包含值和任何由super.saveState返回。该对象将提供给restoreState,其中方法必须从对象中恢复msg并将父状态传递给super.restoreState

1

麦克道威尔的答案做到了。为了完整起见,我添加了两个方法。

public Object saveState(FacesContext context) 
{ 
    Object[] rtrn = new Object[2]; 
    rtrn[0] = super.saveState(context); 
    rtrn[1] = msg; 
    return rtrn; 
} 

public void restoreState(FacesContext context, Object state) 
{ 
    Object[] values = (Object[]) state; 
    super.restoreState(context, values[0]); 
    msg = (String) values[1]; 
}