动态JSF表单:输入字段和Bean之间的链接不起作用

时间:2014-10-29 18:00:27

标签: forms jsf primefaces dynamicform

我创建了一个动态表单,用户可以通过单击命令按钮添加多个日历输入字段。我的问题是,View和Been之间的连接被破坏了。提交表单最初会返回先前在Bean中创建的日期,而不是用户提交的日期。如何解决?

编辑:更改日期并在之后扩展表单而不保存之前会导致丢失更改的日期。即使使用@wittakarn提供的包装器对象的解决方案。

编辑:ajax片段似乎是问题,当我剥离它时它起作用。

DynamicFormBean:

import java.io.Serializable;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class DynamicformBean implements Serializable {

    private static final Logger LOGGER = Logger.getLogger(DynamicformBean.class.getName());
    private List<Date> values;

    @PostConstruct
    public void init() {
        values = new LinkedList<>();
        values.add(new Date());
    }

    public void submit() {
        // save values in database
        LOGGER.info(values.toString());
    }

    public void extend() {
        values.add(new Date());
    }

    public void setValues(List<Date> values) {
        this.values = values;
    }

    public List<Date> getValues() {
        return values;
    }

}

我的观点:dynamicform.xhtml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<f:view xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">

 <h:body>
   <h:form><h2>Dynamicform example</h2>
     <ui:repeat value="#{dynamicformBean.values}" var="value">
       <p:outputLabel for="mask" value="Mask:" />
       <p:calendar id="mask" value="#{value}" pattern="dd.MM.yyyy" mask="true">
         <f:convertDateTime pattern="dd.MM.yyyy" timeZone="CET" />
       </p:calendar>
       <br />
     </ui:repeat>

     <h:commandButton value="Extend">
       <f:ajax listener="#{dynamicformBean.extend}" process="@form" render="@form" />
     </h:commandButton>
     <h:commandButton action="#{dynamicformBean.submit}" value="Save" />

   </h:form>
 </h:body>

</f:view>

日志只打印具有当前日期的元素。

1 个答案:

答案 0 :(得分:0)

我无法详细说明为什么View和Been之间的连接被破坏,但当我将对象日期包装到Data类中时,如下面的代码。问题消失了。

XHTML

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <f:view xmlns="http://www.w3.org/1999/xhtml"
            xmlns:h="http://java.sun.com/jsf/html"
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:ui="http://java.sun.com/jsf/facelets"
            xmlns:p="http://primefaces.org/ui">
        <h:head><title>Dynamicform example</title></h:head>
        <h:body>
            <h:form>
                <h2>Dynamicform example</h2>
                <ui:repeat value="#{dynamicformBean.values}" var="value">                    
                        <p:outputLabel for="mask" value="Mask:" />
                        <p:calendar id="mask" 
                                    value="#{value.date}" 
                                    pattern="dd.MM.yyyy" mask="true">
                            <f:convertDateTime pattern="dd.MM.yyyy" timeZone="CET" />
                        </p:calendar>
                        <br/>
                </ui:repeat>
                <h:commandButton value="Extend">
                    <f:ajax render="@form" 
                            listener="#{dynamicformBean.extend}"/>
                </h:commandButton>
                <h:commandButton action="#{dynamicformBean.submit}" value="Save"/>
            </h:form>
        </h:body>

    </f:view>
</html>

managedbean

@ManagedBean(name = "dynamicformBean")
@ViewScoped
public class DynamicformBean implements Serializable {

    private static final Logger LOGGER = Logger.getLogger(DynamicformBean.class.getName());
    private List<Data> values;

    @PostConstruct
    public void init() {
        values = new LinkedList<Data>();
        values.add(new Data());
    }

    public void submit() {
        // save values in database
        for (Data data : values) {
            LOGGER.info(data.getDate().toString());
        }
    }

    public List<Data> getValues() {
        return values;
    }

    public void setValues(List<Data> values) {
        this.values = values;
    }

    public void extend(AjaxBehaviorEvent event) {
        LOGGER.info("extend");
        values.add(new Data());
    }

}

数据对象

import java.io.Serializable;
import java.util.Date;

public class Data implements Serializable {
    private Date date;

    public Data(){
        date = new Date();
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}

但是,您应该使用JSF标准标签h:head。 PrimeFaces使用它来包含必要的java脚本和CSS代码,用于Ajax工作和花哨的外观。