【问题标题】:JSF doesn't update values in the view when f:validateRegex fails当 f:validateRegex 失败时,JSF 不会更新视图中的值
【发布时间】:2016-08-19 00:52:41
【问题描述】:

我在 Web 应用程序中使用 JSF 2.2,当我使用 f:validateRegex 并失败时,我在视图中遇到问题(因为当我使用 immediate="true" 并尝试再次导航到同一页面时,当我的后备 bean 中有对象的新实例时,视图不会更新)。我在想richfaces有一个错误(因为我在我的主应用程序中使用jsf和richfaces)所以我用richfaces和没有richfaces(只有jsf)制作了一个测试代码来确定错误在哪里,但在这两种情况下视图都失败了.

这是我没有richfaces的测试代码(仅限jsf):

查看:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
    <h:head>
        <title>Mis pruebas con JSF</title>
    </h:head>
    <h:body>
        <h:form id="lista">
            <h:panelGrid id="principal">
                <h:dataTable value="#{indexBB.personas}" var="persona">
                    <h:column>
                        <f:facet name="header">Activo</f:facet>
                        <h:selectBooleanCheckbox value="#{persona.activo}"></h:selectBooleanCheckbox>
                    </h:column>
                    <h:column>
                        <f:facet name="header">Nombre</f:facet>
                        <h:outputText value="#{persona.nombre}"></h:outputText>
                    </h:column>
                    <h:column>
                        <f:facet name="header">Correo</f:facet>
                        <h:outputText value="#{persona.correo}"></h:outputText>
                    </h:column>
                </h:dataTable>
                <h:commandButton action="#{indexBB.crearPersona}" value="Crear Persona">
                </h:commandButton>
                <h:commandButton action="#{indexBB.activarBoton}" value="Activar Boton">
                </h:commandButton>
            </h:panelGrid>
        </h:form>
        <h:form id="crear">
            <h:panelGrid id="secundario" rendered="#{indexBB.crear}">
                <h:outputText value="Activo?">
                </h:outputText>
                <h:selectBooleanCheckbox label="Activo" value="#{indexBB.persona.activo}">
                </h:selectBooleanCheckbox>
                <br></br>
                <h:outputText value="Nombre"></h:outputText>
                <h:inputText label="Nombre" value="#{indexBB.persona.nombre}">
                </h:inputText>
                <br></br>
                <h:outputText value="Correo"></h:outputText>
                <h:inputText label="Nombre" value="#{indexBB.persona.correo}">
                    <f:validateRegex
                        pattern="[\w\.-]*[a-zA-Z0-9_]@[\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]" />
                </h:inputText>
                <br></br>
                <h:commandButton action="#{indexBB.guardarPersona}" value="Guardar Persona">
                </h:commandButton>
                <h:commandButton action="#{indexBB.cancelar}" value="Cancelar" immediate="true">
                </h:commandButton>
            </h:panelGrid>
        </h:form>
    </h:body>
</html>

豆子:

package com.kanayet.martin.view.bb;

import com.kanayet.martin.model.entity.Persona;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Named;
import javax.faces.view.ViewScoped;

@Named(value = "indexBB")
@ViewScoped
public class indexBB implements Serializable {

    private Persona persona;
    private List<Persona> personas;
    private boolean crear;

    /**
     * Creates a new instance of indexBB
     */
    public indexBB() {
    }

    @PostConstruct
    public void onInit(){
        personas = new ArrayList<>();
        personas.add(new Persona("Martin", "martin@gmail.com", true));
        personas.add(new Persona("Andrea", "andrea@gmail.com", true));
        personas.add(new Persona("Camilo", "camilo@gmail.com", true));
        personas.add(new Persona("Felipe", "felipe@gmail.com", true));
        personas.add(new Persona("David", "david@gmail.com", true));
    }

    public void activarBoton() {
        persona = personas.get(0);
    }

    public void crearPersona(){
        crear = true;
        persona = new Persona();
    }

    public void guardarPersona(){
        personas.set(0, persona);
    }

    public void cancelar(){
    }

    public Persona getPersona() {
        return persona;
    }

    public void setPersona(Persona persona) {
        this.persona = persona;
    }

    public List<Persona> getPersonas() {
        return personas;
    }

    public void setPersonas(List<Persona> personas) {
        this.personas = personas;
    }

    public boolean isCrear() {
        return crear;
    }

    public void setCrear(boolean crear) {
        this.crear = crear;
    }

}

模型:(对象)

package com.kanayet.martin.model.entity;   

public class Persona {

    private String nombre;
    private String correo;
    private Boolean activo;

    public Persona() {
    }

    public Persona(String nombre, String correo, Boolean activo) {
        this.nombre = nombre;
        this.correo = correo;
        this.activo = activo;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getCorreo() {
        return correo;
    }

    public void setCorreo(String correo) {
        this.correo = correo;
    }

    public Boolean getActivo() {
        return activo;
    }

    public void setActivo(Boolean activo) {
        this.activo = activo;
    }

}

这是我的 Richfaces 测试代码:(Bean 和 Model 相同)

查看:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:a4j="http://richfaces.org/a4j"
      xmlns:rich="http://richfaces.org/rich"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Mis pruebas con RichFaces</title>
    </h:head>
    <h:body>
        <h:form id="lista">
            <a4j:outputPanel id="principal">
                <rich:dataTable id="personas" value="#{indexBB.personas}"
                                var="persona" rows="50">
                    <rich:column>
                        <h:selectBooleanCheckbox label="Activo" value="#{persona.activo}">
                        </h:selectBooleanCheckbox>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{persona.nombre}"></h:outputText>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{persona.correo}"></h:outputText>
                    </rich:column>
                </rich:dataTable>
                <h:commandButton action="#{indexBB.crearPersona}" value="Crear Persona">
                </h:commandButton>
                <h:commandButton action="#{indexBB.activarBoton}" value="Activar Boton">
                </h:commandButton>
            </a4j:outputPanel>
        </h:form>
        <br></br>
        <h:form id="crear">
            <a4j:outputPanel id="secundario" rendered="#{indexBB.crear}">
                <h:outputText value="Activo?">
                </h:outputText>
                <h:selectBooleanCheckbox label="Activo" value="#{indexBB.persona.activo}">
                </h:selectBooleanCheckbox>
                <br></br>
                <h:outputText value="Nombre"></h:outputText>
                <h:inputText label="Nombre" value="#{indexBB.persona.nombre}">
                </h:inputText>
                <br></br>
                <h:outputText value="Correo"></h:outputText>
                <h:inputText label="Nombre" value="#{indexBB.persona.correo}">
                    <f:validateRegex
                        pattern="[\w\.-]*[a-zA-Z0-9_]@[\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]" />
                </h:inputText>
                <br></br>
                <h:commandButton action="#{indexBB.guardarPersona}" value="Guardar Persona">
                </h:commandButton>
                <h:commandButton action="#{indexBB.cancelar}" value="Cancelar" immediate="true">
                </h:commandButton>
            </a4j:outputPanel>
        </h:form>
    </h:body>
</html>

问题是当我点击“Crear Persona”按钮时,我写了例如“Nombre”:Felix 和“Correo”:Felix 并点击“Guardar Persona”按钮,所以 f:validateRegex 失败,因为不是有效的电子邮件,然后单击“取消”,因为我的最终用户不知道电子邮件所需的值 (immediate="true")。再次,单击“创建角色”按钮,(我的 bean 中的新对象)并且 jsf 页面没有更新,表单应该是空的但它不是,在字段“Nombre”仍然是“Felix”值,但在我的 bean我有一个新的空对象,其属性中没有值,你知道为什么吗?

问题在于是否有richfaces(因为我认为问题可能是richfaces,但事实并非如此),所以我不知道如果我的bean中有一个新对象,为什么jsf页面没有更新,我使用 netbeans 调试工具进行验证,但我是对的,我在 bean 中看到的对象不同(服务器端新对象和空对象)但在我的 JSF 页面“Nombre”具有“Felix”值,我想知道为什么它发生了,我该如何解决这个问题。

非常感谢。

【问题讨论】:

    标签: java jsf backing-beans


    【解决方案1】:

    问题在于 JSF 维护模型的两种表示形式。有 Java 对象 IndexBB,但也有组件树,它跟踪 UI 状态。

    当验证失败时,组件树仍然包含输入的值。 (这是一个有用的功能,用户可以更正这些值。)您使用immediate=true 跳过验证,但这不会重置组件树值。

    在 JSF 2.2 中,您可以使用 resetValues 重置组件树值:

    <h:form id="crear">
        <h:panelGrid id="secundario" rendered="#{indexBB.crear}">
            <h:outputText value="Activo?">
            </h:outputText>
            <h:selectBooleanCheckbox label="Activo" value="#{indexBB.persona.activo}">
            </h:selectBooleanCheckbox>
            <br></br>
            <h:outputText value="Nombre"></h:outputText>
            <h:inputText id="nombreId" label="Nombre" value="#{indexBB.persona.nombre}">
            </h:inputText>
            <br></br>
            <h:outputText value="Correo"></h:outputText>
            <h:inputText id="correoId" label="Nombre" value="#{indexBB.persona.correo}">
                <f:validateRegex
                    pattern="[\w\.-]*[a-zA-Z0-9_]@[\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]" />
            </h:inputText>
            <br></br>
            <h:commandButton  action="#{indexBB.guardarPersona}" value="Guardar Persona">
            </h:commandButton>
            <h:commandButton 
                action="#{indexBB.cancelar}" value="Cancelar">
                <f:ajax resetValues="true" render="crear:nombreId crear:correoId"/>
            </h:commandButton>
        </h:panelGrid>
    </h:form>
    

    变化:

    1. 删除immediate=true
    2. 为要重置的输入添加 ID。
    3. f:ajax 添加到取消按钮。
    4. resetValues 属性添加到f:ajax 并列出您的ID(用空格分隔的ID,而不是逗号)。

    确保您的 cancelar 方法实际上重置了 persona - 您发布的代码不会这样做。

    如果您还想重置错误消息,请将h:messages 添加到表单中,给它一个 ID,然后也重置它。

    另见

    【讨论】:

      猜你喜欢
      • 2014-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-31
      相关资源
      最近更新 更多