jsf复合组件getConvertedValue过早发射

时间:2015-02-24 12:23:57

标签: jsf children composite-component

在我的应用程序中,我创建了一个compositeComponent,其中包含一堆输入字段(例如,street,city,country)。该组件扩展了UIInput,因为我想返回由输入字段创建的完整Location对象。 问题是在提交inputTexts之前触发了compositeComponent的getConvertedValue(),因此值始终为null。

我做错了什么?

复合组件:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:rich="http://richfaces.org/rich"
    xmlns:a4j="http://richfaces.org/a4j" xmlns:p="http://primefaces.org/ui"
    xmlns:composite="http://java.sun.com/jsf/composite">

<composite:interface componentType="locationInput">
    <composite:attribute name="value" />
</composite:interface>


<composite:implementation>
    <style>
.noPadding td {
    padding: 0px !important;
}
</style>
    <span id="#{cc.id}"> <p:panelGrid styleClass="noPadding" id="grd">
            <p:row>
                <p:column>
                    <p:outputLabel value="Straße/Nr." />
                </p:column>
                <p:column>
                    <p:inputText value="#{cc.street}" size="30" required="true" />
                    <p:inputText value="#{cc.houseNr}" size="4" required="true" />
                </p:column>
                <p:column style="width:20px" />
                <p:column>
                    <p:outputLabel value="PLZ" />
                </p:column>
                <p:column>
                    <p:inputText value="#{cc.zipCode}" size="30" required="true" />
                </p:column>
            </p:row>
            <p:row>
                <p:column>
                    <p:outputLabel value="Stadt" />
                </p:column>
                <p:column>
                    <p:inputText value="#{cc.city}" size="30" required="true" />
                </p:column>
                <p:column style="width:20px" />
                <p:column>
                    <p:outputLabel value="Land" />
                </p:column>
                <p:column>
                    <p:autoComplete forceSelection="true" dropdown="true"
                        required="true" cache="true" value="#{cc.country}"
                        completeMethod="#{countryBean.complete}" var="entry"
                        scrollHeight="200" itemValue="#{entry}" itemLabel="#{entry.name}"
                        converter="countryConverter" />
                </p:column>
            </p:row>
        </p:panelGrid>
    </span>
</composite:implementation>
</html>

其FacesComponent类:

import java.io.IOException;

import javax.faces.component.FacesComponent;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIInput;
import javax.faces.component.UINamingContainer;
import javax.faces.context.FacesContext;

@FacesComponent("locationInput")
public class LocationInput extends UIInput implements NamingContainer {

    @Override
    public String getFamily() {
        return UINamingContainer.COMPONENT_FAMILY;
    }

    @Override
    public void encodeBegin(FacesContext context) throws IOException {
        super.encodeBegin(context);
    }

    @Override
    public Object getSubmittedValue() {
        return this;
    }

    @Override
    protected Object getConvertedValue(FacesContext context, Object submittedValue) {
        System.out.println("THIS IS FIRED BEFORE THE COUNTRY/CITY/... gets submitted");
        return new Location(getStreet(), getCity(), getCountry());
    }

    public void setCountry(String country) {
        this.getStateHelper().put("countryValue", country);
    }

    public String getCountry() {
        return (String) this.getStateHelper().get("countryValue");
    }

    public void setCity(String city) {
        this.getStateHelper().put("cityValue", city);
    }

    public String getCity() {
        return (String) this.getStateHelper().get("cityValue");
    }

    public void setZipCode(String zipCode) {
        this.getStateHelper().put("zipCodeValue", zipCode);
    }

    public String getZipCode() {
        return (String) this.getStateHelper().get("zipCodeValue");
    }

    public void setHouseNr(String houseNr) {
        this.getStateHelper().put("houseNrValue", houseNr);
    }

    public String getHouseNr() {
        return (String) this.getStateHelper().get("houseNrValue");
    }

    public void setStreet(String street) {
        this.getStateHelper().put("streetValue", street);
    }

    public String getStreet() {
        return (String) this.getStateHelper().get("streetValue");
    }
}

1 个答案:

答案 0 :(得分:0)

getStreet()getCity()getCountry()将不会更新更新模型值阶段,因此获取null值是正常的您正处于流程验证阶段。

另一种解决方案是在输入中使用binding属性,例如:

 <p:inputText binding="#{cc.street}" size="30" required="true" />

然后在你的支持bean中使用它,如下所示:

private UIInput street;

@Override
public Object getSubmittedValue() {
    ....
   String streetValue = (String) street.getSubmittedValue();
    ....
}

另见: