2015-02-24 8 views
0

В моем приложении я создал составной компонент, который содержит кучу полей ввода (например, улица, город, страна). Компонент расширяет UIInput, потому что я хочу вернуть полный объект Location, созданный полями ввода. Проблема заключается в том, что getConvertedValue() композитного компонента запускается до ввода входных данных, поэтому значения всегда равны нулю.Компонентные компоненты jsf getConvertedValue запущен слишком рано

Что делать неправильно?

Составной компонент:

<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

Нет, ясно нет. Я удалил тег. @OP: внимательно прочитайте описания тегов перед добавлением тегов. – BalusC

ответ

0

getStreet(), getCity() и getCountry() не будут обновлены до тех пор пока модель обновления в Значения Фаза, так что это нормально, чтобы получить значения null, пока вы находитесь в Проверка процесса Фаза.

Альтернативным решением является использование атрибута binding в ваших входах, например:

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

, а затем использовать его, как показано ниже в вашем бэк-боба:

private UIInput street; 

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

Смотрите также:

+0

Спасибо за эту информацию, не знал об этом, так как я довольно новичок в jsf и особенно с составными компонентами. – user3172567

+0

@ user3172567 добро пожаловать – Tarik