Comment fixer le convertisseur de propriétés pour chaque ligne d'une table?
J'ai créé un custom ISO date heure Converter
:
public class IsoDateTimeConverter implements Converter, StateHolder {
private Class type;
private String pattern;
private boolean transientValue = false;
public void setType(Class type) {
this.type = type;
}
public void setPattern(String pattern) {
this.pattern = pattern;
}
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) throws ConverterException {
if (StringCheck.isNullOrEmpty(value)) {
throw new ConverterException("value not specified");
}
try {
if (IsoDate.class.equals(type)) {
if (WebConst.ISO_DATE_NONE.equals(value)) {
return IsoDate.DUMMY;
} else {
//TODO User spezifische TimeZone auslesen
return new IsoDate(value, TimeZone.getDefault().getID());
}
} else if (IsoTime.class.equals(type)) {
if (WebConst.ISO_TIME_NONE.equals(value)) {
return IsoTime.DUMMY;
} else {
//TODO User spezifische TimeZone auslesen
return new IsoTime(value, TimeZone.getDefault().getID());
}
} else if (IsoTimestamp.class.equals(type)) {
if (WebConst.ISO_TIMESTAMP_NONE.equals(value)) {
return IsoTimestamp.DUMMY;
} else {
//TODO User spezifische TimeZone auslesen
return new IsoTimestamp(value, TimeZone.getDefault().getID());
}
} else {
throw new ConverterException("value not convertible");
}
} catch (Exception e) {
throw new ConverterException(e.getMessage());
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) throws ConverterException {
if (value == null) {
throw new ConverterException("value not specified");
}
if (IsoDate.class.equals(value)) {
IsoDate isoDate = (IsoDate) value;
if (isoDate.isDummy()) {
return WebConst.ISO_DATE_NONE;
} else {
//TODO User spezifische TimeZone auslesen
return isoDate.toString(pattern, TimeZone.getDefault().getID(), false);
}
} else if (IsoTime.class.equals(value)) {
IsoTime isoTime = (IsoTime) value;
if (isoTime.isDummy()) {
return WebConst.ISO_TIME_NONE;
} else {
//TODO User spezifische TimeZone auslesen
return isoTime.toString(pattern, TimeZone.getDefault().getID(), false);
}
} else if (IsoTimestamp.class.equals(value)) {
IsoTimestamp isoTimestamp = (IsoTimestamp) value;
if (isoTimestamp.isDummy()) {
return WebConst.ISO_TIMESTAMP_NONE;
} else {
//TODO User spezifische TimeZone auslesen
return isoTimestamp.toString(pattern, TimeZone.getDefault().getID(), false);
}
} else {
throw new ConverterException("value not convertible");
}
}
@Override
public Object saveState(FacesContext context) {
return new Object[]{type, pattern};
}
@Override
public void restoreState(FacesContext context, Object state) {
type = (Class) ((Object[]) state)[0];
pattern = (String) ((Object[]) state)[1];
}
@Override
public boolean isTransient() {
return transientValue;
}
@Override
public void setTransient(boolean transientValue) {
this.transientValue = transientValue;
}
}
Et j'utilise le Converter
comme <mh:IsoDateTimeConverter>
dans la vue suivante:
<p:dataTable value="#{imports.list}" var="item">
<p:column>
<h:outputText value="#{item.balanceDate}" immediate="true">
<mh:IsoDateTimeConverter type="#{webConst.ISO_DATE_CLASS}" pattern="#{webConst.ISO_DATE_FORMAT}"/>
</h:outputText>
</p:column>
</p:dataTable>
Le problème est que lorsque j'ai ouvert ce point de vue, toutes les propriétés sont définies dans mon Converter
classe qu'une seule fois et ensuite la datatable rend et convertit les valeurs fondées sur les propriétés initiales.
J'ai attendu que les propriétés sont définies par ligne. Comment puis-je y parvenir?
Vous devez vous connecter pour publier un commentaire.
Au point, vous attend à ce que le convertisseur de propriétés sont définies à chaque fois qu'une ligne de datatable est rendu. Ce n'est effectivement pas vrai. JSF va créer un seul convertisseur instance par composant lorsque la vue est à construire, il ne va pas créer/réinitialiser le convertisseur chaque fois que la ligne est rendu.
Il y a plusieurs façons de le faire fonctionner.
Passer les attributs dynamiques comme
<f:attribute>
de la composante et de laisser leConverter
intercepter sur que. Vous pouvez trouver un exemple ici: JSF convertDateTime avec le fuseau horaire dans la datatable. Cela peut ensuite être utilisé commeUtiliser un EL fonction, au lieu d'un
Converter
. Vous pouvez trouver un exemple ici: Facelets et JSTL (la Conversion d'une Date en une Chaîne pour l'utiliser dans un champ). Cela peut ensuite être utilisé commeLier le convertisseur et le datatable est
DataModel
comme une propriété de la même managed bean. De cette façon, vous serez en mesure de mettre le convertisseur de propriétés basées sur les données de la ligne avant de le retourner. Voici une base de lancement pour exemple basé sur le standard des composants JSF et standardDateTimeConverter
(cela devrait fonctionner tout aussi bien sur les composants PrimeFaces et avec votre convertisseur personnalisé):avec
(le
Item
classe est juste un haricot avec deux propriétésDate date
etString pattern
)cette résultats dans
Utilisation OmniFaces
<o:converter>
à la place. Il prend en charge, le temps de rendu d'évaluation de EL dans les attributs. Voir aussi le<o:converter>
vitrine exemple.f:convertNumber
(qui correspond à votref:*
modèle) et un attribut dynamiquecurrencyCode="#{rowVar.someCurrencyCode}"
parsomeCurrencyCode
est une propriété d'une entité etrowVar
vient dep:dataTable var="rowVar"
. Donc, je dois écrire mon propre convertisseur ici alors? J'ai déjà Primefaces 6.2, si cela aide. Ou la Omnifaces chose semble assez simple.