Вопрос по validation, components, partial, jsf, jsf-2 – JSF 2 - сохранить все допустимые значения компонентов

3

У меня есть требование создать функцию javascript, которая при вызове сохранит все допустимые компоненты в форме JSF 2.0. Поскольку полная форма никогда не будет действительной в целом, мне нужно найти способ запуска жизненного цикла для каждого компонента, чтобы в случае успешного завершения этапа проверки модель была обновлена и в конечном итоге сохранена.

В идеале это должен быть один ajax-запрос, поскольку итерации по каждому компоненту с отдельным ajax-запросом были бы крайне неэффективными.

Кто-нибудь решил проблему раньше? Если нет, не могли бы вы дать мне несколько советов о возможных реализациях?

Edit:

Вот то, что у меня есть, похоже, пока работает хорошо:

@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;
    }

}

Вызывается с чем-то вроде:

<h:commandButton
    id="saveData">
    <f:ajax listener="#{partialAppSaveBean.saveData}" execute="@form" immediate="true" onevent="onPartialSave" />
</h:commandButton>

Ваш Ответ

1   ответ
2

UIComponent#visitTree() наUIForm.

FacesContext context = FacesContext.getCurrentInstance();
UIForm form = getFormSomehow();
Map<String, Object> validValues = new HashMap<String, Object>();
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;

            if (input.isValid()) {
                validValues.put(input.getClientId(context.getFacesContext()), input.getValue());
            }
        }

        return VisitResult.ACCEPT;
    }
});
Понимаю. Это, кстати, интересная идея для OmniFaces.
Ницца. Если input.isValid (), есть ли простой способ преобразовать значение и обновить модель, к которой привязан компонент? Dave Maple
Хм, это зависит от функциональных требований. Форма уже отправлена / аннулирована заранее, и вы делаете это<f:ajax execute="@this"> только? Или вы все равно хотите отправить и обработать всю форму и подтвердить JSF? Если последнее, ссылатьсяinput.validate(context.getFacesContext()) доif (input.isValid()), Это, кстати, также выполнит преобразование. Он не будет обновлять значения модели, поэтому вам придетсяinput.getValue().
Это было бы отличным дополнением к уже превосходному проекту. Я думаю, что предоставленный вами план должен работать для того, что мне нужно сегодня. Пора идти ложиться код. Dave Maple
Требование состоит в том, что, когда пользователь пытается выйти, я использовал бы метод onbeforeunload, чтобы запросить у них, хотят ли они сохранить свои данные (даже если они неполные), поэтому я буду вызывать эквивалент & lt; f: ajax execute = & quot ; @ форма & Quot; & GT ;. Затем мне нужно обновить модель действительных элементов UIInput и сохранить иерархию моделей. Dave Maple

Похожие вопросы