JSF 2 - Alle gültigen Komponentenwerte speichern
Ich muss eine JavaScript-Funktion erstellen, die beim Aufrufen alle gültigen Komponenten in einem JSF 2.0-Formular speichert. Da das vollständige Formular niemals als Ganzes gültig sein wird, muss ich eine Möglichkeit finden, den Lebenszyklus pro Komponente auszuführen, damit das Modell nach erfolgreicher Validierungsphase aktualisiert und schließlich gespeichert wird.
Idealerweise muss dies eine einzelne Ajax-Anforderung sein, da das Iterieren über jede Komponente mit einer separaten Ajax-Anforderung schmerzhaft ineffizient wäre.
Hat jemand das Problem schon mal gelöst? Wenn nicht, können Sie mir einige Hinweise zu möglichen Implementierungen geben?
Bearbeiten:
Folgendes, was ich habe, scheint bisher gut zu funktionieren:
@ManagedBean(name = "partialAppSaveBean")
@RequestScoped
public class PartialAppSaveBean implements Serializable {
protected static final Logger LOGGER = LoggerFactory.getLogger(PartialAppSaveBean.class);
private static final long serialVersionUID = 1L;
/**
* Save any valid Application values
*
* @param event
*/
public void saveData(AjaxBehaviorEvent event) {
final FacesContext context = FacesContext.getCurrentInstance();
UIForm form = getParentForm(event.getComponent());
Set<VisitHint> hints = EnumSet.of(VisitHint.SKIP_UNRENDERED);
form.visitTree(VisitContext.createVisitContext(context, null, hints), new VisitCallback() {
@Override
public VisitResult visit(VisitContext context, UIComponent component) {
if (component instanceof UIInput) {
UIInput input = (UIInput) component;
input.validate(context.getFacesContext());
if (input.isValid() && input.getValue() != null) {
ValueExpression valueExpression = input.getValueExpression("value");
if (valueExpression != null
&& valueExpression.getExpressionString() != null) {
try {
valueExpression.setValue(context.getFacesContext().getELContext(), input.getValue());
} catch (Exception ex) {
LOGGER.error("Expression [ " + valueExpression.getExpressionString() +
"] value could not be set with value [" + input.getValue() + "]", ex);
}
}
}
}
return VisitResult.ACCEPT;
}
});
//Save data here
}
/**
* Returns the parent form for this UIComponent
*
* @param component
* @return form
*/
private static UIForm getParentForm(UIComponent component) {
while (component.getParent() != null) {
if (component.getParent() instanceof UIForm) {
return (UIForm) component.getParent();
} else {
return getParentForm(component.getParent());
}
}
return null;
}
}
Aufgerufen mit etwas wie:
<h:commandButton
id="saveData">
<f:ajax listener="#{partialAppSaveBean.saveData}" execute="@form" immediate="true" onevent="onPartialSave" />
</h:commandButton>